def test_reset_password(self): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj(POST={ "login": "******", }) entry = Entry(request) _, username, password, _ = entry._loginresetpassword() request = self._create_request_obj(POST={ "login": username, "password": password, }) response = Entry(request).login() assert response.status_int == 200 assert json.loads(response.body.decode("utf-8")) == { "success": True, "username": "******", 'email': '*****@*****.**', "is_password_changed": False, "roles": [{ "name": "__test_role1", "id": self.role1_id, }], "functionalities": {}, } user = DBSession.query(User).filter( User.username == '__test_user1').first() self.assertIsNone(user.temp_password) self.assertIsNotNone(user.password) self.assertNotEqual(len(user.password), 0)
def test_web_client_functionalities(self): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User from tests.functional import create_dummy_request from c2cgeoportal_geoportal.views.entry import Entry request = create_dummy_request() request.static_url = lambda url: "http://example.com/dummy/static/url" request1 = create_dummy_request() request1.static_url = lambda url: "http://example.com/dummy/static/url" request1.user = DBSession.query(User).filter( User.username == "__test_user1").one() request2 = create_dummy_request() request2.static_url = lambda url: "http://example.com/dummy/static/url" request2.user = DBSession.query(User).filter( User.username == "__test_user2").one() settings = { "functionalities": { "anonymous": { "__test_s": "anonymous", "__test_a": ["a1", "a2"] }, "registered": { "__test_s": "registered", "__test_a": ["r1", "r2"] }, "available_in_templates": ["__test_s", "__test_a"], }, "admin_interface": { "available_functionalities": ["__test_a", "__test_s"] }, } functionality.FUNCTIONALITIES_TYPES = None request.registry.settings.update(settings) request1.registry.settings.update(settings) request2.registry.settings.update(settings) annon = Entry(request).get_cgxp_viewer_vars() u1 = Entry(request1).get_cgxp_viewer_vars() u2 = Entry(request2).get_cgxp_viewer_vars() self.assertEqual(annon["functionality"], { "__test_s": ["anonymous"], "__test_a": ["a1", "a2"] }) self.assertEqual(u1["functionality"], { "__test_s": ["registered"], "__test_a": ["r1", "r2"] }) self.assertEqual(u2["functionality"], { "__test_s": ["db"], "__test_a": ["db1", "db2"] })
def _create_entry(self): from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj() request.current_route_url = lambda **kwargs: "http://example.com/current/view" request.registry.settings.update({ "layers": { "enum": { "layer_test": { "attributes": { "label": None } } } }, "api": { "ogc_server": "__test_ogc_server" } }) request.matchdict = { "themes": ["theme"], } entry = Entry(request) request.user = None return entry, request
def test_logout_no_auth(self): from pyramid.httpexceptions import HTTPBadRequest from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj(path="/", params={"came_from": "/came_from"}) entry = Entry(request) self.assertRaises(HTTPBadRequest, entry.logout)
def test_loginchange_no_params(self): from pyramid.httpexceptions import HTTPBadRequest from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj(username="******", params={"lang": "en"}, POST={}) entry = Entry(request) self.assertRaises(HTTPBadRequest, entry.loginchange)
def _create_entry_obj(self, **kwargs): from c2cgeoportal_geoportal.views.entry import Entry kwargs["additional_settings"] = { "admin_interface": { "available_metadata": ["test"] } } return Entry(self._create_request_obj(**kwargs))
def test_themev2_noauth_edit_permission(self): from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj() request.params = {"interface": "main", "version": "2"} entry = Entry(request) themes = entry.themes() self.assertEqual(set(themes["errors"]), set()) self.assertEqual([t["name"] for t in themes["themes"]], [])
def test_logout(self): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj(path="/") request.user = DBSession.query(User).filter_by( username="******").one() response = Entry(request).logout() assert response.status_int == 200 assert response.body.decode("utf-8") == "true" request = self._create_request_obj(path="/") request.route_url = lambda url: "/dummy/route/url" request.user = DBSession.query(User).filter_by( username="******").one() response = Entry(request).logout() assert response.status_int == 200 assert response.body.decode("utf-8") == "true"
def _create_entry_obj(params=None, **kargs): if params is None: params = {} from c2cgeoportal_geoportal.views.entry import Entry request = create_dummy_request(**kargs) request.route_url = lambda url, **kwargs: mapserv_url request.params = params return Entry(request)
def test_error(self): from c2cgeoportal_geoportal.views.entry import Entry entry = Entry(self._create_request_obj(params={ "version": "2", })) themes = entry.themes() self.assertEqual( set(themes["errors"]), set(["The theme has an unsupported name '__test/theme'."]))
def test_theme(self): from c2cgeoportal_geoportal.views.entry import Entry request = testing.DummyRequest({ "version": "2", }) request.static_url = lambda url: "http://example.com/dummy/static/url" request.route_url = lambda url, _query={}: mapserv_url request.client_addr = None request.user = None entry = Entry(request) _, errors = entry._themes(None, "desktop2", True, 2) self.assertEqual(len([e for e in errors if e == "Too many recursions with group '__test_layer_group'"]), 1)
def test_loginchange_different(self): from pyramid.httpexceptions import HTTPBadRequest from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj(username="******", params={"lang": "en"}, POST={ "oldPassword": "******", "newPassword": "******", "confirmNewPassword": "******", }) entry = Entry(request) self.assertRaises(HTTPBadRequest, entry.loginchange)
def test_login(self): from pyramid.httpexceptions import HTTPUnauthorized from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj(params={ "came_from": "/came_from", }, POST={ "login": "******", "password": "******", }) response = Entry(request).login() assert response.status_int == 302 assert response.headers["Location"] == "/came_from" request = self._create_request_obj(POST={ "login": "******", "password": "******", }) response = Entry(request).login() assert response.status_int == 200 assert json.loads(response.body.decode("utf-8")) == { "success": True, "username": "******", 'email': '*****@*****.**', "is_password_changed": False, "roles": [{ "name": "__test_role1", "id": self.role1_id, }], "functionalities": {}, } request = self._create_request_obj(POST={ "login": "******", "password": "******", }) entry = Entry(request) self.assertRaises(HTTPUnauthorized, entry.login)
def test_themev2_auth_no_edit_permission(self): from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj(username="******") request.params = { "interface": "main", } entry = Entry(request) themes = entry.themes() self.assertEqual(set(themes["errors"]), set()) self.assertEqual([t["name"] for t in themes["themes"]], ["__test_theme"]) self.assertEqual([c["name"] for c in themes["themes"][0]["children"]], ["__test_layer_group"]) layers = themes["themes"][0]["children"][0]["children"] self.assertEqual([l["name"] for l in layers], ["__test_private_layer"]) self.assertEqual("editable" in layers[0], False)
def test_no_layers(self): # mapfile error from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj() entry = Entry(request) request.params = {} from c2cgeoportal_geoportal.lib import caching caching.invalidate_region() themes, errors = entry._themes("interface_no_layers") assert themes == [] assert { e[:90] for e in errors } == { "The layer '__test_public_layer_no_layers' do not have any layers", }
def test_theme_geoserver(self): from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj() entry = Entry(request) # unautenticated v1 themes, errors = entry._themes("interface_geoserver") assert { e[:90] for e in errors } == { "The layer '__test_public_layer_geoserver' (__test_public_layer_geoserver) is not defined i" } assert len(themes) == 1 layers = {l["name"] for l in themes[0]["children"][0]["children"]} assert layers == { "__test_public_layer_geoserver", }
def test__get_child_layers_info_with_scalehint(self): import math from pyramid.testing import DummyRequest from c2cgeoportal_geoportal.views.entry import Entry request = DummyRequest() request.user = None entry = Entry(request) class Layer: pass child_layer_1 = Layer() child_layer_1.name = "layer_1" child_layer_1.scaleHint = { "min": 1 * math.sqrt(2), "max": 2 * math.sqrt(2) } child_layer_1.layers = [] child_layer_2 = Layer() child_layer_2.name = "layer_2" child_layer_2.scaleHint = { "min": 3 * math.sqrt(2), "max": 4 * math.sqrt(2) } child_layer_2.layers = [] layer = Layer() layer.layers = [child_layer_1, child_layer_2] child_layers_info = entry._get_child_layers_info_1(layer) expected = [{ "name": "layer_1", "minResolutionHint": 1.0, "maxResolutionHint": 2.0 }, { "name": "layer_2", "minResolutionHint": 3.0, "maxResolutionHint": 4.0 }] self.assertEqual(child_layers_info, expected)
def test_loginchange_good_is_password_changed(self): from c2cgeoportal_geoportal.views.entry import Entry from hashlib import sha1 request = self._create_request_obj(username="******", params={"lang": "en"}, POST={ "oldPassword": "******", "newPassword": "******", "confirmNewPassword": "******" }) assert request.user.is_password_changed is False assert request.user._password == str( sha1("__test_user1".encode("utf-8")).hexdigest()) entry = Entry(request) self.assertNotEqual(entry.loginchange(), None) assert request.user.is_password_changed is True assert request.user._password == str( sha1("1234".encode("utf-8")).hexdigest())
def test_loginchange_good_is_password_changed(self): from c2cgeoportal_geoportal.views.entry import Entry import crypt request = self._create_request_obj(username="******", params={"lang": "en"}, POST={ "oldPassword": "******", "newPassword": "******", "confirmNewPassword": "******" }) assert request.user.is_password_changed is False assert request.user._password == crypt.crypt("__test_user1", request.user._password) entry = Entry(request) self.assertNotEqual(entry.loginchange(), None) assert request.user.is_password_changed is True assert request.user._password == crypt.crypt("1234", request.user._password)
def _create_entry(self): from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj() request.registry.settings.update({ "layers": { "enum": { "layer_test": { "attributes": { "label": None } } } }, "api": { "ogc_server": "__test_ogc_server" }, }) request.matchdict = {"themes": ["theme"]} entry = Entry(request) request.user = None return entry, request
def test_not_in_mapfile(self): # mapfile error from c2cgeoportal_geoportal.views.entry import Entry entry = Entry(self._create_request_obj()) from c2cgeoportal_geoportal.lib import caching caching.invalidate_region() themes, errors = entry._themes("interface_not_in_mapfile") assert len(themes) == 1 groups = {g["name"] for g in themes[0]["children"]} assert groups == { "__test_layer_group", } layers = {l["name"] for l in themes[0]["children"][0]["children"]} assert layers == { "__test_public_layer_not_in_mapfile", } assert { e[:90] for e in errors } == { "The layer '__test_public_layer_not_in_mapfile' (__test_public_layer_not_in_mapfile) is not", }
def test_theme(self): from c2cgeoportal_commons.models import DBSession from c2cgeoportal_commons.models.static import User from c2cgeoportal_geoportal.views.entry import Entry request = self._create_request_obj() entry = Entry(request) # unautenticated themes, errors = entry._themes() assert {e[:90] for e in errors} == set() assert len(themes) == 1 groups = {g["name"] for g in themes[0]["children"]} assert groups == { "__test_layer_group", } layers = {l["name"] for l in themes[0]["children"][0]["children"]} assert layers == { "__test_public_layer", } # authenticated request.params = {} request.user = DBSession.query(User).filter_by( username="******").one() themes, errors = entry._themes() assert {e[:90] for e in errors} == set() assert len(themes) == 1 groups = {g["name"] for g in themes[0]["children"]} assert groups == { "__test_layer_group", } layers = {l["name"] for l in themes[0]["children"][0]["children"]} assert layers == { "__test_private_layer_edit", "__test_public_layer", "__test_private_layer", }
def test__get_child_layers_info_without_scalehint(self): from pyramid.testing import DummyRequest from c2cgeoportal_geoportal.views.entry import Entry request = DummyRequest() request.user = None entry = Entry(request) class Layer: pass child_layer_1 = Layer() child_layer_1.name = "layer_1" child_layer_1.scaleHint = None child_layer_1.layers = [] child_layer_2 = Layer() child_layer_2.name = "layer_2" child_layer_2.scaleHint = None child_layer_2.layers = [] layer = Layer() layer.layers = [child_layer_1, child_layer_2] child_layers_info = entry._get_child_layers_info_1(layer) expected = [{ "name": "layer_1", "minResolutionHint": 0.0, "maxResolutionHint": 999999999.0, }, { "name": "layer_2", "minResolutionHint": 0.0, "maxResolutionHint": 999999999.0, }] self.assertEqual(child_layers_info, expected)
def test_notmapfile(self): # mapfile error from c2cgeoportal_geoportal.views.entry import Entry entry = Entry(self._create_request_obj()) from c2cgeoportal_geoportal.lib import caching caching.invalidate_region() themes, errors = entry._themes("interface_notmapfile") assert len(themes) == 1 groups = {g["name"] for g in themes[0]["children"]} assert groups == { "__test_layer_group", } layers = {l["name"] for l in themes[0]["children"][0]["children"]} assert layers == { "__test_public_layer_notmapfile", } assert { e[:90] for e in errors } == { "The layer '__test_public_layer_notmapfile' (__test_public_layer_notmapfile) is not defined", "GetCapabilities from URL http://mapserver:8080/?map=not_a_mapfile&SERVICE=WMS&VERSION=1.1." }
def _create_entry_obj(self, **kwargs): from c2cgeoportal_geoportal.views.entry import Entry return Entry(self._create_request_obj(**kwargs))
def test_themes_edit_columns_extras(self): from c2cgeoportal_geoportal.views.entry import Entry from c2cgeoportal_commons.models.main import Metadata metadatas = [ Metadata("lastUpdateDateColumn", "last_update_date"), Metadata("lastUpdateUserColumn", "last_update_user"), ] layer_id = self._create_layer(geom_type=False, exclude_properties=True, metadatas=metadatas) entry = Entry( self._get_request(layer_id, username="******", params={"interface": "main"})) themes = entry.themes() layers = themes["themes"][0]["children"][0]["children"] self.assertEqual( [layer["edit_columns"] for layer in layers], [[ { "nillable": True, "type": "xsd:integer", "name": "child_id" }, { "nillable": True, "type": "xsd:boolean", "name": "deleted" }, { "nillable": True, "type": "xsd:date", "name": "date" }, { "nillable": True, "type": "xsd:time", "name": "start_time" # }, { # "nillable": True, # "type": "xsd:duration", # "name": "interval" }, { "nillable": True, "type": "xsd:string", "name": "short_name1" }, { "nillable": True, "type": "xsd:string", "name": "short_name2", "maxLength": 50 }, { "nillable": True, "type": "xsd:integer", "name": "short_number" }, { "nillable": True, "type": "xsd:double", "name": "double_number" }, { "nillable": True, "type": "xsd:base64Binary", "name": "large_binary" }, { "enumeration": [ "one", "two", "three", ], "type": "xsd:string", "name": "value", "nillable": True, "restriction": "enumeration" }, { "fractionDigits": 2, "nillable": True, "type": "xsd:decimal", "name": "numeric", "totalDigits": 5, }, { "name": "numeric2", "type": "xsd:decimal", "nillable": True }, { "srid": 21781, "nillable": True, "type": "gml:GeometryPropertyType", "name": "geom" }, { "restriction": "enumeration", "nillable": True, "type": "xsd:string", "name": "child", "enumeration": ["c1\xe9", "c2\xe9"] } ]])
def test_themes_edit_columns(self): from c2cgeoportal_geoportal.views.entry import Entry layer_id = self._create_layer(geom_type=True) entry = Entry( self._get_request(layer_id, username="******", params={ "version": "2", "interface": "main" })) themes = entry.themes() layers = themes["themes"][0]["children"][0]["children"] self.assertEqual( [layer["edit_columns"] for layer in layers], [[ { "nillable": True, "type": "xsd:integer", "name": "child_id" }, { "type": "xsd:string", "name": "name" }, { "nillable": True, "type": "xsd:boolean", "name": "deleted" }, { "nillable": True, "type": "xsd:string", "name": "last_update_user" }, { "nillable": True, "type": "xsd:dateTime", "name": "last_update_date" }, { "nillable": True, "type": "xsd:date", "name": "date" }, { "nillable": True, "type": "xsd:time", "name": "start_time" # }, { # "nillable": True, # "type": "xsd:duration", # "name": "interval" }, { "nillable": True, "type": "xsd:string", "name": "short_name1" }, { "nillable": True, "type": "xsd:string", "name": "short_name2", "maxLength": 50 }, { "nillable": True, "type": "xsd:integer", "name": "short_number" }, { "nillable": True, "type": "xsd:double", "name": "double_number" }, { "nillable": True, "type": "xsd:base64Binary", "name": "large_binary" }, { "enumeration": [ "one", "two", "three", ], "type": "xsd:string", "name": "value", "nillable": True, "restriction": "enumeration" }, { "fractionDigits": 2, "nillable": True, "type": "xsd:decimal", "name": "numeric", "totalDigits": 5 }, { "nillable": True, "type": "xsd:decimal", "name": "numeric2" }, { "srid": 21781, "nillable": True, "type": "gml:PointPropertyType", "name": "geom" }, { "restriction": "enumeration", "nillable": True, "type": "xsd:string", "name": "child", "enumeration": ["c1\xe9", "c2\xe9"] } ]])
def test_metadata(self): from c2cgeoportal_geoportal.views.entry import Entry types = [ {"name": "string", "type": "string"}, {"name": "list", "type": "list"}, {"name": "boolean", "type": "boolean"}, {"name": "boolean2", "type": "boolean"}, {"name": "boolean3", "type": "boolean"}, {"name": "integer", "type": "integer"}, {"name": "float", "type": "float"}, {"name": "json", "type": "json"}, {"name": "json_wrong", "type": "json"}, {"name": "date", "type": "date"}, {"name": "time", "type": "time"}, {"name": "datetime", "type": "datetime"}, {"name": "date2", "type": "date"}, {"name": "time2", "type": "time"}, {"name": "datetime2", "type": "datetime"}, {"name": "unknown", "type": "unknown"}, ] types += [{"name": "url{}".format(n), "type": "url"} for n in range(1, 21)] request = create_dummy_request(additional_settings={ "package": "tests", "servers": { "server": "http://example.com/test" }, "admin_interface": {"available_metadata": types} }) def route_url(url, **kwargs): del url del kwargs return "http://mapserver.org/" request.route_url = route_url def static_url(url, **kwargs): del kwargs return "http://dummy.org/{}".format(url) request.static_url = static_url request.params = { "interface": "desktop", } entry = Entry(request) themes = entry.themes() self.assertEqual(self._get_filtered_errors(themes), set([ "The boolean attribute 'boolean3'='hello' is not in [yes, y, on, 1, true, no, n, off, 0, false].", "Unable to parse the attribute 'json_wrong'='{\"test\": 123' with the type 'json', error:\n'set' object has no attribute 'append'", "The date attribute 'date2'='Sep 25 10:36:28 BRST 2003' should not have any time", "The time attribute 'time2'='Sep 25 10:36:28 BRST 2003' should not have any date", "Unable to parse the attribute 'datetime2'='Hello' with the type 'datetime', error:\n('Unknown string format:', 'Hello')", "The attribute 'url11'='https:///static/icon.png' is not a valid URL.", "The attribute 'url12'='static://test' cannot have an empty path.", "The attribute 'url13'='static://test/' cannot have an empty path.", "The attribute 'url14'='config:///static/icon.png' cannot have an empty netloc.", "The attribute 'url15': The server 'unknown_server' (config://unknown_server) is not found in the config: [server]", "The attribute 'url16'='https://' is not a valid URL.", "The attribute 'url17'='https:///' is not a valid URL.", "The attribute 'url18'='https:///static' is not a valid URL.", "The attribute 'url19'='' is not an URL.", "The attribute 'url20'='/' is not an URL.", "Unknown type 'unknown'.", ])) self.assertEqual( [self._only_name(t, "metadata") for t in themes["themes"]], [{ "metadata": {}, "children": [{ "metadata": {}, "children": [{ "metadata": { "string": "string", "list": ["1", "2", "a"], "boolean": True, "boolean2": False, "integer": 1, "float": 5.5, "json": {"test": 123}, "date": "2003-09-25", "time": "10:36:28", "datetime": "2003-09-25T10:36:28", "url1": "http://example.com/hi?a=b#c", "url2": "http://dummy.org//etc/geomapfish/static/path/icon.png", "url3": "http://dummy.org//etc/geomapfish/static/path/icon.png", "url4": "http://dummy.org/tests_geoportal:cgxp/path/icon.png", "url5": "http://dummy.org/project:static/path/icon.png", "url6": "http://dummy.org/project:cgxp/path/icon.png", "url7": "http://example.com/test", "url8": "http://example.com/test/index.html", "url9": "/dummy/static/icon.png", "url10": "dummy/static/icon.png", } }] }] }] )
def test_login(self): from pyramid.testing import DummyRequest from c2cgeoportal_geoportal.views.entry import Entry request = DummyRequest() request.is_valid_referer = True request.user = None entry = Entry(request) request.path = "/for_test" expected = { "lang": "fr", "came_from": "/for_test", } self.assertEqual(entry.loginform403(), expected) request.params = { "came_from": "/for_a_second_test", } entry = Entry(request) expected = { "lang": "fr", "came_from": "/for_a_second_test", } self.assertEqual(entry.loginform(), expected) entry = Entry(request) request.params = {} expected = { "lang": "fr", "came_from": "/", } self.assertEqual(entry.loginform(), expected) request.registry.settings = { "functionalities": { "anonymous": { "func": ["anon"], "toto": "titi" }, "registered": { "func": ["reg"] }, "available_in_templates": ["func"] }, "admin_interface": { "available_functionalities": [{ "name": "func" }] } } entry = Entry(request) expected = {"functionalities": {"func": ["anon"]}} self.assertEqual(entry.loginuser(), expected) class G: id = 123 def __init__(self, name, functionalities): self.name = name self.functionalities = functionalities class U: username = "******" is_password_changed = True email = "*****@*****.**" def __init__(self, role="__test_role", functionalities=None): if functionalities is None: functionalities = [] self.roles = [G(role, functionalities)] request.user = U() entry = Entry(request) expected = { "success": True, "username": "******", "email": "*****@*****.**", "is_password_changed": True, "roles": [{ "name": "__test_role", "id": 123, }], "functionalities": { "func": ["reg"] } } self.assertEqual(entry.loginuser(), expected) class F: name = "func" value = "user" request.user = U("__test_role2", [F()]) entry = Entry(request) expected = { "success": True, "username": "******", 'email': '*****@*****.**', "is_password_changed": True, "roles": [{ "name": "__test_role2", "id": 123, }], "functionalities": { "func": ["user"] } } self.assertEqual(entry.loginuser(), expected)