Skip to content

Commit 75476f6

Browse files
committed
[tests] Add test for common ws endpoint
1 parent fb09331 commit 75476f6

File tree

4 files changed

+59
-52
lines changed

4 files changed

+59
-52
lines changed

openwisp_controller/geo/channels/consumers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import swapper
2-
from django_loci.channels.base import BaseAllLocationBroadcast, BaseLocationBroadcast
2+
from django_loci.channels.base import BaseCommonLocationBroadcast, BaseLocationBroadcast
33

44
Location = swapper.load_model("geo", "Location")
55

@@ -19,7 +19,7 @@ def is_authorized(self, user, location):
1919
return result
2020

2121

22-
class AllLocationBroadcast(BaseAllLocationBroadcast):
22+
class CommonLocationBroadcast(BaseCommonLocationBroadcast):
2323
model = Location
2424

2525
def is_autherized(self, user, location):

openwisp_controller/geo/channels/routing.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
from channels.security.websocket import AllowedHostsOriginValidator
44
from django.urls import path
55
from django_loci.channels.base import (
6-
all_location_broadcast_path,
6+
common_location_broadcast_path,
77
location_broadcast_path,
88
)
99
from openwisp_notifications.websockets.routing import (
1010
get_routes as get_notification_routes,
1111
)
1212

13-
from .consumers import AllLocationBroadcast, LocationBroadcast
13+
from .consumers import CommonLocationBroadcast, LocationBroadcast
1414

1515

1616
def get_routes():
@@ -19,8 +19,8 @@ def get_routes():
1919
location_broadcast_path, LocationBroadcast.as_asgi(), name="LocationChannel"
2020
),
2121
path(
22-
all_location_broadcast_path,
23-
AllLocationBroadcast.as_asgi(),
22+
common_location_broadcast_path,
23+
CommonLocationBroadcast.as_asgi(),
2424
name="AllLocationChannel",
2525
),
2626
]

openwisp_controller/geo/tests/pytest.py

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
import importlib
21
import os
32
from unittest import skipIf
43

54
import pytest
65
from channels.db import database_sync_to_async
76
from channels.routing import ProtocolTypeRouter
8-
from channels.testing import WebsocketCommunicator
97
from django.conf import settings
10-
from django.contrib.auth import get_user_model, login
8+
from django.contrib.auth import get_user_model
119
from django.contrib.auth.models import Permission
12-
from django.http.request import HttpRequest
1310
from django.utils.module_loading import import_string
11+
from django_loci.tests.base.test_channels import BaseTestChannels
1412
from swapper import load_model
1513

1614
from .utils import TestGeoMixin
@@ -23,48 +21,13 @@
2321

2422

2523
@skipIf(os.environ.get("SAMPLE_APP", False), "Running tests on SAMPLE_APP")
26-
class TestChannels(TestGeoMixin):
24+
class TestChannels(TestGeoMixin, BaseTestChannels):
2725
application = import_string(getattr(settings, "ASGI_APPLICATION"))
2826
object_model = Device
2927
location_model = Location
3028
object_location_model = DeviceLocation
3129
user_model = get_user_model()
3230

33-
def _force_login(self, user, backend=None):
34-
engine = importlib.import_module(settings.SESSION_ENGINE)
35-
request = HttpRequest()
36-
request.session = engine.SessionStore()
37-
login(request, user, backend)
38-
request.session.save()
39-
return request.session
40-
41-
async def _get_request_dict(self, pk=None, user=None):
42-
if not pk:
43-
location = await database_sync_to_async(self._create_location)(
44-
is_mobile=True
45-
)
46-
await database_sync_to_async(self._create_object_location)(
47-
location=location
48-
)
49-
pk = location.pk
50-
path = "/ws/loci/location/{0}/".format(pk)
51-
session = None
52-
if user:
53-
session = await database_sync_to_async(self._force_login)(user)
54-
return {"pk": pk, "path": path, "session": session}
55-
56-
def _get_communicator(self, request_vars, user=None):
57-
communicator = WebsocketCommunicator(self.application, request_vars["path"])
58-
if user:
59-
communicator.scope.update(
60-
{
61-
"user": user,
62-
"session": request_vars["session"],
63-
"url_route": {"kwargs": {"pk": request_vars["pk"]}},
64-
}
65-
)
66-
return communicator
67-
6831
@pytest.mark.asyncio
6932
@pytest.mark.django_db(transaction=True)
7033
async def test_consumer_staff_but_no_change_permission(self):
@@ -74,8 +37,51 @@ async def test_consumer_staff_but_no_change_permission(self):
7437
location = await database_sync_to_async(self._create_location)(is_mobile=True)
7538
await database_sync_to_async(self._create_object_location)(location=location)
7639
pk = location.pk
77-
request_vars = await self._get_request_dict(user=user, pk=pk)
78-
communicator = self._get_communicator(request_vars, user)
40+
request_vars = await self._get_specific_location_request_dict(user=user, pk=pk)
41+
communicator = self._get_specific_location_communicator(request_vars, user)
42+
connected, _ = await communicator.connect()
43+
assert not connected
44+
await communicator.disconnect()
45+
# add permission to change location and repeat
46+
perm = await database_sync_to_async(
47+
(
48+
await database_sync_to_async(Permission.objects.filter)(
49+
name="Can change location"
50+
)
51+
).first
52+
)()
53+
await database_sync_to_async(user.user_permissions.add)(perm)
54+
user = await database_sync_to_async(User.objects.get)(pk=user.pk)
55+
request_vars = await self._get_specific_location_request_dict(user=user, pk=pk)
56+
communicator = self._get_specific_location_communicator(request_vars, user)
57+
connected, _ = await communicator.connect()
58+
assert not connected
59+
await communicator.disconnect()
60+
# add user to organization
61+
await database_sync_to_async(OrganizationUser.objects.create)(
62+
organization=location.organization, user=user, is_admin=True
63+
)
64+
await database_sync_to_async(location.organization.save)()
65+
user = await database_sync_to_async(User.objects.get)(pk=user.pk)
66+
request_vars = await self._ge_get_specific_location_request_dictt_request_dict(
67+
user=user, pk=pk
68+
)
69+
communicator = self._get_specific_location_communicator(request_vars, user)
70+
connected, _ = await communicator.connect()
71+
assert connected
72+
await communicator.disconnect()
73+
74+
@pytest.mark.asyncio
75+
@pytest.mark.django_db(transaction=True)
76+
async def test_common_location_consumer_staff_but_no_change_permission(self):
77+
user = await database_sync_to_async(User.objects.create_user)(
78+
username="user", password="password", email="[email protected]", is_staff=True
79+
)
80+
location = await database_sync_to_async(self._create_location)(is_mobile=True)
81+
await database_sync_to_async(self._create_object_location)(location=location)
82+
pk = location.pk
83+
request_vars = await self._get_common_location_request_dict(user=user, pk=pk)
84+
communicator = self._get_common_location_communicator(request_vars, user)
7985
connected, _ = await communicator.connect()
8086
assert not connected
8187
await communicator.disconnect()
@@ -89,8 +95,8 @@ async def test_consumer_staff_but_no_change_permission(self):
8995
)()
9096
await database_sync_to_async(user.user_permissions.add)(perm)
9197
user = await database_sync_to_async(User.objects.get)(pk=user.pk)
92-
request_vars = await self._get_request_dict(user=user, pk=pk)
93-
communicator = self._get_communicator(request_vars, user)
98+
request_vars = await self._get_common_location_request_dict(user=user, pk=pk)
99+
communicator = self._get_common_location_communicator(request_vars, user)
94100
connected, _ = await communicator.connect()
95101
assert not connected
96102
await communicator.disconnect()
@@ -100,8 +106,8 @@ async def test_consumer_staff_but_no_change_permission(self):
100106
)
101107
await database_sync_to_async(location.organization.save)()
102108
user = await database_sync_to_async(User.objects.get)(pk=user.pk)
103-
request_vars = await self._get_request_dict(user=user, pk=pk)
104-
communicator = self._get_communicator(request_vars, user)
109+
request_vars = await self._get_common_location_request_dict(user=user, pk=pk)
110+
communicator = self._get_common_location_communicator(request_vars, user)
105111
connected, _ = await communicator.connect()
106112
assert connected
107113
await communicator.disconnect()

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ django-reversion~=6.0.0
33
django-taggit~=6.1.0
44
netjsonconfig @ https://github.com/openwisp/netjsonconfig/archive/refs/heads/1.3.tar.gz
55
django-x509 @ https://github.com/openwisp/django-x509/archive/refs/heads/1.4.tar.gz
6+
# Todo: Make path https://github.com/openwisp/django-loci/archive/refs/heads/1.3.tar.gz before merge
67
django-loci @ https://github.com/openwisp/django-loci/tarball/feature/191-new-ws-endpoint-for-all-location
78
django-flat-json-widget @ https://github.com/openwisp/django-flat-json-widget/archive/refs/heads/0.5.tar.gz
89
openwisp-users @ https://github.com/openwisp/openwisp-users/archive/refs/heads/1.3.tar.gz

0 commit comments

Comments
 (0)