2018-05-19 04:54:08 -05:00
import json
import pytest
from django . contrib . auth import get_user_model
from django . urls import reverse
2023-03-27 09:26:32 -05:00
from django . core . signing import Signer
2018-05-19 04:54:08 -05:00
from umap . models import DataLayer , Map
from . base import login_required
pytestmark = pytest . mark . django_db
User = get_user_model ( )
@pytest.fixture
def post_data ( ) :
return {
' name ' : ' name ' ,
' center ' : ' { " type " : " Point " , " coordinates " :[13.447265624999998,48.94415123418794]} ' , # noqa
' settings ' : ' { " type " : " Feature " , " geometry " : { " type " : " Point " , " coordinates " :[5.0592041015625,52.05924589011585]}, " properties " : { " tilelayer " : { " maxZoom " :20, " url_template " : " http:// {s} .tile.openstreetmap.fr/hot/ {z} / {x} / {y} .png " , " minZoom " :0, " attribution " : " HOT and friends " }, " licence " : " " , " description " : " " , " name " : " test enrhûmé " , " tilelayersControl " :true, " displayDataBrowserOnLoad " :false, " displayPopupFooter " :true, " displayCaptionOnLoad " :false, " miniMap " :true, " moreControl " :true, " scaleControl " :true, " zoomControl " :true, " datalayersControl " :true, " zoom " :8}} ' # noqa
}
def test_create ( client , user , post_data ) :
url = reverse ( ' map_create ' )
# POST only mendatory fields
name = ' test-map-with-new-name '
post_data [ ' name ' ] = name
client . login ( username = user . username , password = " 123123 " )
response = client . post ( url , post_data )
assert response . status_code == 200
j = json . loads ( response . content . decode ( ) )
created_map = Map . objects . latest ( ' pk ' )
assert j [ ' id ' ] == created_map . pk
assert created_map . name == name
2018-09-08 15:42:11 -05:00
assert created_map . center . x == 13.447265624999998
assert created_map . center . y == 48.94415123418794
2018-09-23 02:56:30 -05:00
assert j [ ' permissions ' ] == {
' edit_status ' : 3 ,
' share_status ' : 1 ,
' owner ' : {
' id ' : user . pk ,
' name ' : ' Joe ' ,
' url ' : ' /en/user/Joe/ '
} ,
' editors ' : [ ] ,
' anonymous_edit_url ' : ( ' http://umap.org '
+ created_map . get_anonymous_edit_url ( ) )
}
2018-05-19 04:54:08 -05:00
def test_map_create_permissions ( client , settings ) :
2018-05-19 10:16:34 -05:00
settings . UMAP_ALLOW_ANONYMOUS = False
2018-05-19 04:54:08 -05:00
url = reverse ( ' map_create ' )
# POST anonymous
response = client . post ( url , { } )
assert login_required ( response )
def test_map_update_access ( client , map , user ) :
url = reverse ( ' map_update ' , kwargs = { ' map_id ' : map . pk } )
# GET anonymous
response = client . get ( url )
assert login_required ( response )
# POST anonymous
response = client . post ( url , { } )
assert login_required ( response )
# GET with wrong permissions
client . login ( username = user . username , password = " 123123 " )
response = client . get ( url )
assert response . status_code == 403
# POST with wrong permissions
client . login ( username = user . username , password = " 123123 " )
response = client . post ( url , { } )
assert response . status_code == 403
def test_map_update_permissions_access ( client , map , user ) :
url = reverse ( ' map_update_permissions ' , kwargs = { ' map_id ' : map . pk } )
# GET anonymous
response = client . get ( url )
assert login_required ( response )
# POST anonymous
response = client . post ( url , { } )
assert login_required ( response )
# GET with wrong permissions
client . login ( username = user . username , password = " 123123 " )
response = client . get ( url )
assert response . status_code == 403
# POST with wrong permissions
client . login ( username = user . username , password = " 123123 " )
response = client . post ( url , { } )
assert response . status_code == 403
def test_update ( client , map , post_data ) :
url = reverse ( ' map_update ' , kwargs = { ' map_id ' : map . pk } )
# POST only mendatory fields
name = ' new map name '
post_data [ ' name ' ] = name
client . login ( username = map . owner . username , password = " 123123 " )
response = client . post ( url , post_data )
assert response . status_code == 200
j = json . loads ( response . content . decode ( ) )
assert ' html ' not in j
updated_map = Map . objects . get ( pk = map . pk )
assert j [ ' id ' ] == updated_map . pk
assert updated_map . name == name
def test_delete ( client , map , datalayer ) :
url = reverse ( ' map_delete ' , args = ( map . pk , ) )
client . login ( username = map . owner . username , password = " 123123 " )
response = client . post ( url , { } , follow = True )
assert response . status_code == 200
assert not Map . objects . filter ( pk = map . pk ) . exists ( )
assert not DataLayer . objects . filter ( pk = datalayer . pk ) . exists ( )
# Check that user has not been impacted
assert User . objects . filter ( pk = map . owner . pk ) . exists ( )
# Test response is a json
j = json . loads ( response . content . decode ( ) )
assert ' redirect ' in j
def test_wrong_slug_should_redirect_to_canonical ( client , map ) :
url = reverse ( ' map ' , kwargs = { ' pk ' : map . pk , ' slug ' : ' wrong-slug ' } )
canonical = reverse ( ' map ' , kwargs = { ' pk ' : map . pk ,
' slug ' : map . slug } )
response = client . get ( url )
assert response . status_code == 301
assert response [ ' Location ' ] == canonical
def test_wrong_slug_should_redirect_with_query_string ( client , map ) :
url = reverse ( ' map ' , kwargs = { ' pk ' : map . pk , ' slug ' : ' wrong-slug ' } )
url = " {} ?allowEdit=0 " . format ( url )
canonical = reverse ( ' map ' , kwargs = { ' pk ' : map . pk ,
' slug ' : map . slug } )
canonical = " {} ?allowEdit=0 " . format ( canonical )
response = client . get ( url )
assert response . status_code == 301
assert response [ ' Location ' ] == canonical
def test_should_not_consider_the_query_string_for_canonical_check ( client , map ) :
url = reverse ( ' map ' , kwargs = { ' pk ' : map . pk , ' slug ' : map . slug } )
url = " {} ?allowEdit=0 " . format ( url )
response = client . get ( url )
assert response . status_code == 200
def test_short_url_should_redirect_to_canonical ( client , map ) :
url = reverse ( ' map_short_url ' , kwargs = { ' pk ' : map . pk } )
canonical = reverse ( ' map ' , kwargs = { ' pk ' : map . pk ,
' slug ' : map . slug } )
response = client . get ( url )
assert response . status_code == 301
assert response [ ' Location ' ] == canonical
def test_clone_map_should_create_a_new_instance ( client , map ) :
assert Map . objects . count ( ) == 1
url = reverse ( ' map_clone ' , kwargs = { ' map_id ' : map . pk } )
client . login ( username = map . owner . username , password = " 123123 " )
response = client . post ( url )
assert response . status_code == 200
assert Map . objects . count ( ) == 2
clone = Map . objects . latest ( ' pk ' )
assert clone . pk != map . pk
assert clone . name == u " Clone of " + map . name
def test_user_not_allowed_should_not_clone_map ( client , map , user , settings ) :
2018-05-19 10:16:34 -05:00
settings . UMAP_ALLOW_ANONYMOUS = False
2018-05-19 04:54:08 -05:00
assert Map . objects . count ( ) == 1
url = reverse ( ' map_clone ' , kwargs = { ' map_id ' : map . pk } )
map . edit_status = map . OWNER
map . save ( )
response = client . post ( url )
assert login_required ( response )
client . login ( username = user . username , password = " 123123 " )
response = client . post ( url )
assert response . status_code == 403
map . edit_status = map . ANONYMOUS
map . save ( )
client . logout ( )
response = client . post ( url )
assert response . status_code == 403
assert Map . objects . count ( ) == 1
def test_clone_should_set_cloner_as_owner ( client , map , user ) :
url = reverse ( ' map_clone ' , kwargs = { ' map_id ' : map . pk } )
map . edit_status = map . EDITORS
map . editors . add ( user )
map . save ( )
client . login ( username = user . username , password = " 123123 " )
response = client . post ( url )
assert response . status_code == 200
assert Map . objects . count ( ) == 2
clone = Map . objects . latest ( ' pk ' )
assert clone . pk != map . pk
assert clone . name == u " Clone of " + map . name
assert clone . owner == user
def test_map_creation_should_allow_unicode_names ( client , map , post_data ) :
url = reverse ( ' map_create ' )
# POST only mendatory fields
name = u ' Академический '
post_data [ ' name ' ] = name
client . login ( username = map . owner . username , password = " 123123 " )
response = client . post ( url , post_data )
assert response . status_code == 200
j = json . loads ( response . content . decode ( ) )
created_map = Map . objects . latest ( ' pk ' )
assert j [ ' id ' ] == created_map . pk
assert created_map . name == name
# Lower case of the russian original name
# self.assertEqual(created_map.slug, u"академический")
# for now we fallback to "map", see unicode_name branch
assert created_map . slug == ' map '
def test_anonymous_can_access_map_with_share_status_public ( client , map ) :
url = reverse ( ' map ' , args = ( map . slug , map . pk ) )
map . share_status = map . PUBLIC
map . save ( )
response = client . get ( url )
assert response . status_code == 200
def test_anonymous_can_access_map_with_share_status_open ( client , map ) :
url = reverse ( ' map ' , args = ( map . slug , map . pk ) )
map . share_status = map . OPEN
map . save ( )
response = client . get ( url )
assert response . status_code == 200
def test_anonymous_cannot_access_map_with_share_status_private ( client , map ) :
url = reverse ( ' map ' , args = ( map . slug , map . pk ) )
map . share_status = map . PRIVATE
map . save ( )
response = client . get ( url )
assert response . status_code == 403
def test_owner_can_access_map_with_share_status_private ( client , map ) :
url = reverse ( ' map ' , args = ( map . slug , map . pk ) )
map . share_status = map . PRIVATE
map . save ( )
client . login ( username = map . owner . username , password = " 123123 " )
response = client . get ( url )
assert response . status_code == 200
def test_editors_can_access_map_with_share_status_private ( client , map , user ) :
url = reverse ( ' map ' , args = ( map . slug , map . pk ) )
map . share_status = map . PRIVATE
map . editors . add ( user )
map . save ( )
client . login ( username = user . username , password = " 123123 " )
response = client . get ( url )
assert response . status_code == 200
2019-04-07 04:12:38 -05:00
def test_anonymous_cannot_access_map_with_share_status_blocked ( client , map ) :
url = reverse ( ' map ' , args = ( map . slug , map . pk ) )
map . share_status = map . BLOCKED
map . save ( )
response = client . get ( url )
assert response . status_code == 403
def test_owner_cannot_access_map_with_share_status_blocked ( client , map ) :
url = reverse ( ' map ' , args = ( map . slug , map . pk ) )
map . share_status = map . BLOCKED
map . save ( )
client . login ( username = map . owner . username , password = " 123123 " )
response = client . get ( url )
assert response . status_code == 403
2018-05-19 04:54:08 -05:00
def test_non_editor_cannot_access_map_if_share_status_private ( client , map , user ) : # noqa
url = reverse ( ' map ' , args = ( map . slug , map . pk ) )
map . share_status = map . PRIVATE
map . save ( )
client . login ( username = user . username , password = " 123123 " )
response = client . get ( url )
assert response . status_code == 403
def test_map_geojson_view ( client , map ) :
url = reverse ( ' map_geojson ' , args = ( map . pk , ) )
response = client . get ( url )
j = json . loads ( response . content . decode ( ) )
2018-07-14 16:55:21 -05:00
assert ' json ' in response [ ' content-type ' ]
2018-05-19 04:54:08 -05:00
assert ' type ' in j
def test_only_owner_can_delete ( client , map , user ) :
map . editors . add ( user )
url = reverse ( ' map_delete ' , kwargs = { ' map_id ' : map . pk } )
client . login ( username = user . username , password = " 123123 " )
response = client . post ( url , { } , follow = True )
assert response . status_code == 403
def test_map_editors_do_not_see_owner_change_input ( client , map , user ) :
map . editors . add ( user )
map . edit_status = map . EDITORS
map . save ( )
url = reverse ( ' map_update_permissions ' , kwargs = { ' map_id ' : map . pk } )
client . login ( username = user . username , password = " 123123 " )
response = client . get ( url )
assert ' id_owner ' not in response
def test_logged_in_user_can_edit_map_editable_by_anonymous ( client , map , user ) :
map . owner = None
map . edit_status = map . ANONYMOUS
map . save ( )
client . login ( username = user . username , password = " 123123 " )
url = reverse ( ' map_update ' , kwargs = { ' map_id ' : map . pk } )
new_name = ' this is my new name '
data = {
' center ' : ' { " type " : " Point " , " coordinates " :[13.447265624999998,48.94415123418794]} ' , # noqa
' name ' : new_name
}
response = client . post ( url , data )
assert response . status_code == 200
assert Map . objects . get ( pk = map . pk ) . name == new_name
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_anonymous_create ( cookieclient , post_data ) :
url = reverse ( ' map_create ' )
# POST only mendatory fields
name = ' test-map-with-new-name '
post_data [ ' name ' ] = name
response = cookieclient . post ( url , post_data )
assert response . status_code == 200
j = json . loads ( response . content . decode ( ) )
created_map = Map . objects . latest ( ' pk ' )
assert j [ ' id ' ] == created_map . pk
2018-09-23 02:56:30 -05:00
assert ( created_map . get_anonymous_edit_url ( )
in j [ ' permissions ' ] [ ' anonymous_edit_url ' ] )
2018-05-19 04:54:08 -05:00
assert created_map . name == name
key , value = created_map . signed_cookie_elements
assert key in cookieclient . cookies
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_anonymous_update_without_cookie_fails ( client , anonymap , post_data ) : # noqa
url = reverse ( ' map_update ' , kwargs = { ' map_id ' : anonymap . pk } )
response = client . post ( url , post_data )
assert response . status_code == 403
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_anonymous_update_with_cookie_should_work ( cookieclient , anonymap , post_data ) : # noqa
url = reverse ( ' map_update ' , kwargs = { ' map_id ' : anonymap . pk } )
# POST only mendatory fields
name = ' new map name '
post_data [ ' name ' ] = name
response = cookieclient . post ( url , post_data )
assert response . status_code == 200
j = json . loads ( response . content . decode ( ) )
updated_map = Map . objects . get ( pk = anonymap . pk )
assert j [ ' id ' ] == updated_map . pk
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_anonymous_delete ( cookieclient , anonymap ) :
url = reverse ( ' map_delete ' , args = ( anonymap . pk , ) )
response = cookieclient . post ( url , { } , follow = True )
assert response . status_code == 200
assert not Map . objects . filter ( pk = anonymap . pk ) . count ( )
# Test response is a json
j = json . loads ( response . content . decode ( ) )
assert ' redirect ' in j
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_no_cookie_cant_delete ( client , anonymap ) :
url = reverse ( ' map_delete ' , args = ( anonymap . pk , ) )
response = client . post ( url , { } , follow = True )
assert response . status_code == 403
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_anonymous_edit_url ( cookieclient , anonymap ) :
url = anonymap . get_anonymous_edit_url ( )
canonical = reverse ( ' map ' , kwargs = { ' pk ' : anonymap . pk ,
' slug ' : anonymap . slug } )
response = cookieclient . get ( url )
assert response . status_code == 302
assert response [ ' Location ' ] == canonical
key , value = anonymap . signed_cookie_elements
assert key in cookieclient . cookies
2023-03-27 09:26:32 -05:00
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_sha1_anonymous_edit_url ( cookieclient , anonymap ) :
signer = Signer ( algorithm = ' sha1 ' )
signature = signer . sign ( anonymap . pk )
url = reverse ( ' map_anonymous_edit_url ' , kwargs = { ' signature ' : signature } )
canonical = reverse ( ' map ' , kwargs = { ' pk ' : anonymap . pk ,
' slug ' : anonymap . slug } )
response = cookieclient . get ( url )
assert response . status_code == 302
assert response [ ' Location ' ] == canonical
key , value = anonymap . signed_cookie_elements
assert key in cookieclient . cookies
2018-05-19 04:54:08 -05:00
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_bad_anonymous_edit_url_should_return_403 ( cookieclient , anonymap ) :
url = anonymap . get_anonymous_edit_url ( )
url = reverse (
' map_anonymous_edit_url ' ,
kwargs = { ' signature ' : " %s :badsignature " % anonymap . pk }
)
response = cookieclient . get ( url )
assert response . status_code == 403
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_clone_anonymous_map_should_not_be_possible_if_user_is_not_allowed ( client , anonymap , user ) : # noqa
assert Map . objects . count ( ) == 1
url = reverse ( ' map_clone ' , kwargs = { ' map_id ' : anonymap . pk } )
anonymap . edit_status = anonymap . OWNER
anonymap . save ( )
response = client . post ( url )
assert response . status_code == 403
client . login ( username = user . username , password = " 123123 " )
response = client . post ( url )
assert response . status_code == 403
assert Map . objects . count ( ) == 1
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_clone_map_should_be_possible_if_edit_status_is_anonymous ( client , anonymap ) : # noqa
assert Map . objects . count ( ) == 1
url = reverse ( ' map_clone ' , kwargs = { ' map_id ' : anonymap . pk } )
anonymap . edit_status = anonymap . ANONYMOUS
anonymap . save ( )
response = client . post ( url )
assert response . status_code == 200
assert Map . objects . count ( ) == 2
clone = Map . objects . latest ( ' pk ' )
assert clone . pk != anonymap . pk
assert clone . name == ' Clone of ' + anonymap . name
assert clone . owner is None
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_anyone_can_access_anonymous_map ( cookieclient , anonymap ) :
url = reverse ( ' map ' , args = ( anonymap . slug , anonymap . pk ) )
anonymap . share_status = anonymap . PUBLIC
response = cookieclient . get ( url )
assert response . status_code == 200
anonymap . share_status = anonymap . OPEN
response = cookieclient . get ( url )
assert response . status_code == 200
anonymap . share_status = anonymap . PRIVATE
response = cookieclient . get ( url )
assert response . status_code == 200
2018-07-07 09:44:40 -05:00
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_map_attach_owner ( cookieclient , anonymap , user ) :
url = reverse ( ' map_attach_owner ' , kwargs = { ' map_id ' : anonymap . pk } )
cookieclient . login ( username = user . username , password = " 123123 " )
assert anonymap . owner is None
response = cookieclient . post ( url )
assert response . status_code == 200
map = Map . objects . get ( pk = anonymap . pk )
assert map . owner == user
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_map_attach_owner_not_logged_in ( cookieclient , anonymap , user ) :
url = reverse ( ' map_attach_owner ' , kwargs = { ' map_id ' : anonymap . pk } )
assert anonymap . owner is None
response = cookieclient . post ( url )
assert response . status_code == 403
@pytest.mark.usefixtures ( ' allow_anonymous ' )
def test_map_attach_owner_with_already_an_owner ( cookieclient , map , user ) :
url = reverse ( ' map_attach_owner ' , kwargs = { ' map_id ' : map . pk } )
cookieclient . login ( username = user . username , password = " 123123 " )
assert map . owner
assert map . owner != user
response = cookieclient . post ( url )
assert response . status_code == 403
def test_map_attach_owner_anonymous_not_allowed ( cookieclient , anonymap , user ) :
url = reverse ( ' map_attach_owner ' , kwargs = { ' map_id ' : anonymap . pk } )
cookieclient . login ( username = user . username , password = " 123123 " )
assert anonymap . owner is None
response = cookieclient . post ( url )
assert response . status_code == 403
# # GET anonymous
# response = client.get(url)
# assert login_required(response)
# # POST anonymous
# response = client.post(url, {})
# assert login_required(response)
# # GET with wrong permissions
# client.login(username=user.username, password="123123")
# response = client.get(url)
# assert response.status_code == 403
# # POST with wrong permissions
# client.login(username=user.username, password="123123")
# response = client.post(url, {})
# assert response.status_code == 403
2018-09-07 15:12:39 -05:00
def test_create_readonly ( client , user , post_data , settings ) :
settings . UMAP_READONLY = True
url = reverse ( ' map_create ' )
client . login ( username = user . username , password = " 123123 " )
response = client . post ( url , post_data )
assert response . status_code == 403
2018-09-08 09:49:25 -05:00
assert response . content == b ' Site is readonly for maintenance '
2023-05-11 04:33:08 -05:00
def test_search ( client , map ) :
# Very basic search, that do not deal with accent nor case.
# See install.md for how to have a smarter dict + index.
map . name = " Blé dur "
map . save ( )
url = reverse ( " search " )
response = client . get ( url + " ?q=Blé " )
assert " Blé dur " in response . content . decode ( )