From 541043399f866965b2ed81576c2bae9d733b8601 Mon Sep 17 00:00:00 2001 From: Gagan Deep Date: Tue, 27 Aug 2024 17:32:02 +0530 Subject: [PATCH] [fix] Dashboard timeseries chart should respect MONITORING_API_BASEURL Django admin should make API request to MONITORING_API_BASEURL. --- openwisp_monitoring/device/apps.py | 10 +- .../device/static/monitoring/js/device-map.js | 115 ++++++++++-------- .../static/monitoring/js/chart-utils.js | 3 + openwisp_monitoring/tests/test_selenium.py | 38 ++++++ 4 files changed, 112 insertions(+), 54 deletions(-) diff --git a/openwisp_monitoring/device/apps.py b/openwisp_monitoring/device/apps.py index 67d988073..0f61a5f05 100644 --- a/openwisp_monitoring/device/apps.py +++ b/openwisp_monitoring/device/apps.py @@ -427,6 +427,14 @@ def register_dashboard_items(self): } } + dashboard_chart_url = reverse_lazy( + 'monitoring_general:api_dashboard_timeseries', + urlconf=MONITORING_API_URLCONF, + ) + if MONITORING_API_BASEURL: + dashboard_chart_url = urljoin( + MONITORING_API_BASEURL, str(dashboard_chart_url) + ) register_dashboard_template( position=55, config={ @@ -450,7 +458,7 @@ def register_dashboard_items(self): ), }, extra_config={ - 'api_url': reverse_lazy('monitoring_general:api_dashboard_timeseries'), + 'api_url': dashboard_chart_url, 'default_time': Chart.DEFAULT_TIME, 'chart_quick_links': general_wifi_client_quick_links, }, diff --git a/openwisp_monitoring/device/static/monitoring/js/device-map.js b/openwisp_monitoring/device/static/monitoring/js/device-map.js index 1ab0f3dcf..00fc8a15a 100644 --- a/openwisp_monitoring/device/static/monitoring/js/device-map.js +++ b/openwisp_monitoring/device/static/monitoring/js/device-map.js @@ -54,65 +54,74 @@ loadingOverlay.show(); - $.getJSON(url, function (data) { - let html = '', - device; - for (let i = 0; i < data.results.length; i++) { - device = data.results[i]; - html += ` - - ${device.name} - - - ${device.monitoring.status_label} - - - `; - } - let pagination = '', - parts = []; - if (data.previous || data.next) { - if (data.previous) { - parts.push(``); + $.ajax({ + dataType: "json", + url: url, + xhrFields: { + withCredentials: true + }, + success: function (data) { + let html = '', + device; + for (let i = 0; i < data.results.length; i++) { + device = data.results[i]; + html += ` + + ${device.name} + + + ${device.monitoring.status_label} + + + `; } - if (data.next) { - parts.push(``); + let pagination = '', + parts = []; + if (data.previous || data.next) { + if (data.previous) { + parts.push(``); + } + if (data.next) { + parts.push(``); + } + pagination = `

${parts.join(' ')}`; } - pagination = `

${parts.join(' ')}`; - } - layer.bindPopup(` -

-

${layer.feature.properties.name} (${data.count})

- - - - - - - - - ${html} - -
${gettext('name')}${gettext('status')}
- ${pagination} -
`); - layer.openPopup(); + layer.bindPopup(` +
+

${layer.feature.properties.name} (${data.count})

+ + + + + + + + + ${html} + +
${gettext('name')}${gettext('status')}
+ ${pagination} +
`); + layer.openPopup(); - // bind next/prev buttons - let el = $(layer.getPopup().getElement()); - el.find('.next').click(function () { - loadPopUpContent(layer, $(this).data('url')); - }); - el.find('.prev').click(function () { - loadPopUpContent(layer, $(this).data('url')); - }); + // bind next/prev buttons + let el = $(layer.getPopup().getElement()); + el.find('.next').click(function () { + loadPopUpContent(layer, $(this).data('url')); + }); + el.find('.prev').click(function () { + loadPopUpContent(layer, $(this).data('url')); + }); - loadingOverlay.hide(); + loadingOverlay.hide(); - }).fail(function () { - loadingOverlay.hide(); - alert(gettext('Error while retrieving data')); + }, + error: function () { + loadingOverlay.hide(); + alert(gettext('Error while retrieving data')); + } }); + }; const leafletConfig = JSON.parse($('#leaflet-config').text()); const tiles = leafletConfig.TILES.map((tile) => { diff --git a/openwisp_monitoring/monitoring/static/monitoring/js/chart-utils.js b/openwisp_monitoring/monitoring/static/monitoring/js/chart-utils.js index 3584854b7..edf32a846 100644 --- a/openwisp_monitoring/monitoring/static/monitoring/js/chart-utils.js +++ b/openwisp_monitoring/monitoring/static/monitoring/js/chart-utils.js @@ -236,6 +236,9 @@ django.jQuery(function ($) { loadCharts = function (time, showLoading) { $.ajax(getChartFetchUrl(time), { dataType: 'json', + xhrFields: { + withCredentials: true + }, beforeSend: function () { chartContents.hide(); chartContents.empty(); diff --git a/openwisp_monitoring/tests/test_selenium.py b/openwisp_monitoring/tests/test_selenium.py index 8bab42117..4f27801ab 100644 --- a/openwisp_monitoring/tests/test_selenium.py +++ b/openwisp_monitoring/tests/test_selenium.py @@ -16,6 +16,7 @@ ) from openwisp_monitoring.monitoring.configuration import DEFAULT_DASHBOARD_TRAFFIC_CHART from openwisp_monitoring.monitoring.migrations import create_general_metrics +from openwisp_utils.admin_theme.dashboard import DASHBOARD_TEMPLATES from openwisp_utils.test_selenium_mixins import ( SeleniumTestMixin as BaseSeleniumTestMixin, ) @@ -30,6 +31,43 @@ class SeleniumTestMixin(BaseSeleniumTestMixin): + @classmethod + def setUpClass(cls): + """ + Sets up the necessary configurations for the test environment, ensuring + that the dashboard templates render correctly during Selenium tests. + + During testing, the `OPENWISP_MONITORING_API_BASEURL` is set to + `http://testserver`, a dummy value for the test environment. The dashboard + templates are registered in the `AppConfig.ready` method, and these + templates depend on specific URLs being correctly configured. + + Since mocking the `OPENWISP_MONITORING_API_BASEURL` does not update the + URLs in the already registered dashboard templates, this method manually + adjusts the template contexts to ensure they contain the correct URLs. + """ + super().setUpClass() + cls._dashboard_map_context = DASHBOARD_TEMPLATES[0][1].copy() + cls._dashboard_timeseries_context = DASHBOARD_TEMPLATES[55][1].copy() + DASHBOARD_TEMPLATES[0][1] = { + 'monitoring_device_list_url': reverse( + 'monitoring:api_location_device_list', + args=['000'], + ), + 'monitoring_location_geojson_url': reverse( + 'monitoring:api_location_geojson' + ), + } + DASHBOARD_TEMPLATES[55][1]['api_url'] = reverse( + 'monitoring_general:api_dashboard_timeseries' + ) + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + DASHBOARD_TEMPLATES[0][1] = cls._dashboard_map_context + DASHBOARD_TEMPLATES[55][1] = cls._dashboard_timeseries_context + def setUp(self): self.admin = self._create_admin( username=self.admin_username, password=self.admin_password