def test_layer_upload(self):
        """ Try uploading a layer and verify that the user can administrate
        his own layer despite not being a site administrator.
        """

        from django.contrib.auth.models import User
        from geonode.maps.utils import save

        # TODO: Would be nice to ensure the name is available before running the test...
        norman = User.objects.get(username="******")
        save(
            "lembang_schools_by_norman",
            os.path.join(TEST_DATA, "lembang_schools.shp"),
            norman,
            overwrite=False,
            abstract="Schools which are in Lembang",
            title="Lembang Schools",
            permissions={"users": []},
        )

        # No assertion, but this will raise an error if the permissions don't
        # allow metadata editing
        get_web_page(
            settings.SITEURL + "data/geonode:lembang_schools_by_norman?describe",
            username="******",
            password="******",
            login_url=LOGIN_URL,
        )
 def test_empty_bbox(self):
     """Regression-test for failures caused by zero-width bounding boxes"""
     thefile = os.path.join(TEST_DATA, "single_point.shp")
     uploaded = file_upload(thefile, overwrite=True)
     detail_page_url = urljoin(settings.SITEURL, uploaded.get_absolute_url())
     get_web_page(detail_page_url)  # no assertion, but this will fail if the page 500's
     new_map_url = urljoin(settings.SITEURL, "/maps/new") + "?" + urlencode(dict(layer=uploaded.typename))
     get_web_page(new_map_url)  # no assertion, but this will fail if the page 500's
    def test_search_result_detail(self):
        # Test with a valid UUID
        uuid = Layer.objects.all()[0].uuid
        test_url = "%sdata/search/detail/?uuid=%s" % (settings.SITEURL, uuid)
        results = get_web_page(test_url)

        # Test with an invalid UUID (should return 404, but currently does not)
        uuid = "xyz"
        test_url = "%sdata/search/detail/?uuid=%s" % (settings.SITEURL, uuid)
        # Should use assertRaisesRegexp here, but new in 2.7
        self.assertRaises(urllib2.HTTPError, lambda: get_web_page(test_url))
    def test_metadata_search(self):

        # Test Empty Search [returns all results, should match len(Layer.objects.all())+5]
        # +5 is for the 5 'default' records in GeoNetwork
        test_url = "%sdata/search/api/?q=%s&start=%d&limit=%d" % (settings.SITEURL, "", 0, 10)
        results = json.loads(get_web_page(test_url))
        self.assertEquals(int(results["total"]), Layer.objects.count())

        # Test n0ch@nc3 Search (returns no results)
        test_url = "%sdata/search/api/?q=%s&start=%d&limit=%d" % (settings.SITEURL, "n0ch@nc3", 0, 10)
        results = json.loads(get_web_page(test_url))
        self.assertEquals(int(results["total"]), 0)

        # Test Keyword Search (various search terms)
        test_url = "%sdata/search/api/?q=%s&start=%d&limit=%d" % (settings.SITEURL, "NIC", 0, 10)
        results = json.loads(get_web_page(test_url))
        # self.assertEquals(int(results["total"]), 3)

        # This Section should be greatly expanded upon after uploading several
        # Test layers. Issues found with GeoNetwork search should be 'documented'
        # here with a Test Case

        # Test BBOX Search (various bbox)

        # - Test with an empty query string and Global BBOX and validate that total is correct
        test_url = "%sdata/search/api/?q=%s&start=%d&limit=%d&bbox=%s" % (
            settings.SITEURL,
            "",
            0,
            10,
            "-180,-90,180,90",
        )
        results = json.loads(get_web_page(test_url))
        self.assertEquals(int(results["total"]), Layer.objects.count())

        # - Test with a specific query string and a bbox that is disjoint from its results
        # test_url = "%sdata/search/api/?q=%s&start=%d&limit=%d&bbox=%s"  % (settings.SITEURL, "NIC", 0, 10, "0,-90,180,90")
        # results = json.loads(get_web_page(test_url))
        # self.assertEquals(int(results["total"]), 0)

        # - Many more Tests required

        # Test start/limit params (do in unit test?)

        # Test complex/compound Search

        # Test Permissions applied to search from ACLs

        # TODO Write a method to accept a perm_spec and query params and test that query results are returned respecting the perm_spec

        # - Test with Anonymous User
        perm_spec = {"anonymous": "_none", "authenticated": "_none", "users": [["admin", "layer_readwrite"]]}
        for layer in Layer.objects.all():
            set_layer_permissions(layer, perm_spec)

        test_url = "%sdata/search/api/?q=%s&start=%d&limit=%d" % (settings.SITEURL, "", 0, 10)

        results = json.loads(get_web_page(test_url))

        for layer in results["rows"]:
            if layer["_local"] == False:
                # Ignore non-local layers
                pass
            else:
                self.assertEquals(layer["_permissions"]["view"], False)
                self.assertEquals(layer["_permissions"]["change"], False)
                self.assertEquals(layer["_permissions"]["delete"], False)
                self.assertEquals(layer["_permissions"]["change_permissions"], False)

        # - Test with Authenticated User
        results = json.loads(get_web_page(test_url, username="******", password="******", login_url=LOGIN_URL))

        for layer in results["rows"]:
            if layer["_local"] == False:
                # Ignore non-local layers
                pass
            else:
                self.assertEquals(layer["_permissions"]["view"], True)
                self.assertEquals(layer["_permissions"]["change"], True)
                self.assertEquals(layer["_permissions"]["delete"], True)
                self.assertEquals(layer["_permissions"]["change_permissions"], True)
    def test_layer_upload(self):
        """Test that layers can be uploaded to running GeoNode/GeoServer
        """
        layers = {}
        expected_layers = []
        not_expected_layers = []
        datadir = TEST_DATA
        BAD_LAYERS = ["lembang_schools_percentage_loss.shp"]

        for filename in os.listdir(datadir):
            basename, extension = os.path.splitext(filename)
            if extension.lower() in [".tif", ".shp", ".zip"]:
                if filename not in BAD_LAYERS:
                    expected_layers.append(os.path.join(datadir, filename))
                else:
                    not_expected_layers.append(os.path.join(datadir, filename))
        uploaded = upload(datadir)

        for item in uploaded:
            errors = "errors" in item
            if errors:
                # should this file have been uploaded?
                if item["file"] in not_expected_layers:
                    continue
                msg = "Could not upload %s. " % item["file"]
                assert errors is False, msg + "Error was: %s" % item["errors"]
                msg = 'Upload should have returned either "name" or ' '"errors" for file %s.' % item["file"]
            else:
                assert "name" in item, msg
                layers[item["file"]] = item["name"]

        msg = "There were %s compatible layers in the directory," " but only %s were sucessfully uploaded" % (
            len(expected_layers),
            len(layers),
        )
        # assert len(layers) == len(expected_layers), msg

        uploaded_layers = [layer for layer in layers.items()]

        for layer in expected_layers:
            msg = "The following file should have been uploaded" "but was not: %s. " % layer
            assert layer in layers, msg

            layer_name = layers[layer]

            # Check the layer is in the Django database
            Layer.objects.get(name=layer_name)

            # Check that layer is in geoserver
            found = False
            gs_username, gs_password = settings.GEOSERVER_CREDENTIALS
            page = get_web_page(
                os.path.join(settings.GEOSERVER_BASE_URL, "rest/layers"), username=gs_username, password=gs_password
            )
            if page.find("rest/layers/%s.html" % layer_name) > 0:
                found = True
            if not found:
                msg = (
                    "Upload could not be verified, the layer %s is not "
                    "in geoserver %s, but GeoNode did not raise any errors, "
                    "this should never happen." % (layer_name, settings.GEOSERVER_BASE_URL)
                )
                raise GeoNodeException(msg)

        server_url = settings.GEOSERVER_BASE_URL + "ows?"
        # Verify that the GeoServer GetCapabilities record is accesible:
        # metadata = get_layers_metadata(server_url, '1.0.0')
        # msg = ('The metadata list should not be empty in server %s'
        #        % server_url)
        # assert len(metadata) > 0, msg
        # Check the keywords are recognized too

        # Clean up and completely delete the layers
        for layer in expected_layers:
            layer_name = layers[layer]
            Layer.objects.get(name=layer_name).delete()