Skip to content

Commit e1d4e69

Browse files
[fix] Fixed unsaved changes alert for readonly map #560
For readonly mode the field name used to track geometry field is different leading to its json value not being parsed, hence leading to unsaved_changes alert. A small change of addition of the said field in 'jsonValues' of 'unsaved_changes.js' Fixed it. Also increased the timeout for waiting of success message present for selenium test of device admin to tackle TimeoutException. Closes #560 Signed-off-by: DragnEmperor <[email protected]> Co-authored-by: Federico Capoano <[email protected]>
1 parent 751e9b2 commit e1d4e69

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

openwisp_controller/config/static/config/js/unsaved_changes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"config-0-config",
1212
"config-0-context",
1313
"devicelocation-0-geometry",
14+
"geometry",
1415
];
1516
// ignore fields that have no name attribute, begin with "_" or "initial-"
1617
if (

openwisp_controller/geo/tests/test_selenium.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
from django.contrib.auth import get_user_model
2+
from django.contrib.auth.models import Permission
23
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
4+
from django.test import tag
5+
from django.urls.base import reverse
6+
from django_loci.tests import TestAdminMixin
37
from django_loci.tests.base.test_selenium import BaseTestDeviceAdminSelenium
48
from selenium.webdriver.common.by import By
59
from swapper import load_model
610

711
from openwisp_users.tests.utils import TestOrganizationMixin
12+
from openwisp_utils.tests import SeleniumTestMixin
13+
14+
from .utils import TestGeoMixin
815

916
Device = load_model('config', 'Device')
1017
Location = load_model('geo', 'Location')
1118
FloorPlan = load_model('geo', 'FloorPlan')
1219
DeviceLocation = load_model('geo', 'DeviceLocation')
1320

1421

15-
class TestDeviceAdminSelenium(
22+
# these tests are for geo elements on device admin
23+
@tag('selenium_tests')
24+
class TestDeviceAdminGeoSelenium(
1625
BaseTestDeviceAdminSelenium, TestOrganizationMixin, StaticLiveServerTestCase
1726
):
1827
app_label = 'geo'
@@ -27,6 +36,10 @@ class TestDeviceAdminSelenium(
2736
def _get_prefix(cls):
2837
return cls.inline_field_prefix
2938

39+
# set timeout to 5 seconds to allow enough time for presence of elements
40+
def wait_for_presence(self, by, value, timeout=5, driver=None):
41+
return super().wait_for_presence(by, value, timeout, driver)
42+
3043
def _fill_device_form(self):
3144
org = self._get_org()
3245
self.find_element(by=By.NAME, value='mac_address').send_keys(
@@ -46,3 +59,54 @@ def _fill_device_form(self):
4659
)
4760
self.find_element(by=By.CLASS_NAME, value='select2-results__option').click()
4861
super()._fill_device_form()
62+
63+
64+
@tag('selenium_tests')
65+
class TestDeviceAdminReadonly(
66+
TestGeoMixin,
67+
TestAdminMixin,
68+
SeleniumTestMixin,
69+
StaticLiveServerTestCase,
70+
):
71+
browser = 'chrome'
72+
app_label = 'geo'
73+
74+
object_model = Device
75+
location_model = Location
76+
object_location_model = DeviceLocation
77+
permission_model = Permission
78+
user_model = get_user_model()
79+
80+
# for these tests we need readonly user with view permissions.
81+
def setUp(self):
82+
self.admin = self._create_readonly_admin(
83+
username=self.admin_username,
84+
password=self.admin_password,
85+
models=[self.object_model, self.location_model, self.object_location_model],
86+
)
87+
88+
def test_unsaved_changes_readonly(self):
89+
self.login()
90+
ol = self._create_object_location()
91+
path = reverse('admin:config_device_change', args=[ol.device.id])
92+
93+
with self.subTest('Alert should not be displayed without any change'):
94+
self.open(path)
95+
self.hide_loading_overlay()
96+
# The WebDriver automatically accepts the
97+
# beforeunload confirmation dialog. To verify the message,
98+
# we log it to the console and check its content.
99+
#
100+
# our own JS code sets e.returnValue when triggered
101+
# so we just need to ensure it's set as expected
102+
self.web_driver.execute_script(
103+
'django.jQuery(window).on("beforeunload", function(e) {'
104+
' console.warn(e.returnValue); });'
105+
)
106+
self.web_driver.refresh()
107+
for entry in self.get_browser_logs():
108+
if (
109+
entry['level'] == 'WARNING'
110+
and "You haven\'t saved your changes yet!" in entry['message']
111+
):
112+
self.fail('Unsaved changes alert displayed without any change')

openwisp_controller/geo/tests/utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ def _create_object_location(self, **kwargs):
5959
return ol
6060

6161
def _create_readonly_admin(self, **kwargs):
62+
# remove organization before proceeding to user creation
63+
org1 = kwargs.pop('organization', None)
6264
user = super()._create_readonly_admin(**kwargs)
63-
org1 = self._create_organization()
65+
if not org1:
66+
org1 = self._create_organization()
6467
OrganizationUser.objects.create(user=user, organization=org1, is_admin=True)
6568
return user

0 commit comments

Comments
 (0)