def test_register_dashboard_chart(self): from openwisp_utils.admin_theme.dashboard import DASHBOARD_CHARTS dashboard_element = { 'name': 'Test Chart', 'query_params': { 'app_label': 'app_label', 'model': 'model_name', 'group_by': 'property', }, 'colors': { 'value1': 'red', 'value2': 'green' }, } with self.subTest('Registering new dashboard element'): register_dashboard_chart(-1, dashboard_element) self.assertIn(-1, DASHBOARD_CHARTS) with self.subTest('Registering a chart at existing position'): with self.assertRaises(ImproperlyConfigured): register_dashboard_chart(-1, dashboard_element) with self.subTest('Unregistering a chart that does not exists'): with self.assertRaises(ImproperlyConfigured): unregister_dashboard_chart('Chart Test') with self.subTest('Unregistering "Test Chart"'): unregister_dashboard_chart('Test Chart') self.assertNotIn(-1, DASHBOARD_CHARTS)
def test_miscellaneous_DASHBOARD_CHARTS_validation(self): with self.subTest('Registering with incomplete config'): with self.assertRaises(AssertionError): register_dashboard_chart(-1, dict()) with self.subTest('Registering with invalid position argument'): with self.assertRaises(ImproperlyConfigured): register_dashboard_chart(['Test Chart'], dict()) with self.subTest('Registering with invalid config'): with self.assertRaises(ImproperlyConfigured): register_dashboard_chart(-1, tuple()) with self.subTest('Unregistering with invalid name'): with self.assertRaises(ImproperlyConfigured): unregister_dashboard_chart(dict()) with self.subTest('Test filters required when not group_by'): with self.assertRaises(AssertionError) as ctx: register_dashboard_chart( -1, { 'name': 'Test Chart', 'query_params': { 'app_label': 'app_label', 'model': 'model_name', 'annotate': {}, }, }, ) self.assertIn('filters', str(ctx.exception))
def test_non_existent_model(self): register_dashboard_chart( -1, { 'name': 'Test Chart', 'query_params': { 'app_label': 'app_label', 'model': 'model_name', 'group_by': 'property', }, }, ) with self.assertRaises(ImproperlyConfigured): self.client.get(reverse('admin:index')) unregister_dashboard_chart('Test Chart')
def register_dashboard_items(self): register_dashboard_chart( position=0, config={ 'name': _('Monitoring Status'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'monitoring__status', }, 'colors': { 'ok': '#267126', 'problem': '#ffb442', 'critical': '#a72d1d', 'unknown': '#353c44', }, 'labels': { 'ok': app_settings.HEALTH_STATUS_LABELS['ok'], 'problem': app_settings.HEALTH_STATUS_LABELS['problem'], 'critical': app_settings.HEALTH_STATUS_LABELS['critical'], 'unknown': app_settings.HEALTH_STATUS_LABELS['unknown'], }, }, ) if app_settings.DASHBOARD_MAP: register_dashboard_template( position=0, config={ 'template': 'admin/dashboard/device_map.html', 'css': ( 'monitoring/css/device-map.css', 'leaflet/leaflet.css', 'monitoring/css/leaflet.fullscreen.css', ), 'js': ( 'monitoring/js/device-map.js', 'leaflet/leaflet.js', 'leaflet/leaflet.extras.js', 'monitoring/js/leaflet.fullscreen.min.js', ), }, )
def register_dashboard_charts(self): register_dashboard_chart( position=2, config={ 'name': _('Geographic positioning'), 'query_params': { 'app_label': 'config', 'model': 'device', 'annotate': { 'with_geo': Count( Case(When( devicelocation__isnull=False, then=1, ))), 'without_geo': Count(Case(When( devicelocation__isnull=True, then=1, ))), }, 'aggregate': { 'with_geo__sum': Sum('with_geo'), 'without_geo__sum': Sum('without_geo'), }, }, 'colors': { 'with_geo__sum': '#267126', 'without_geo__sum': '#353c44' }, 'labels': { 'with_geo__sum': _('With geographic position'), 'without_geo__sum': _('Without geographic position'), }, 'filters': { 'key': 'with_geo', 'with_geo__sum': 'true', 'without_geo__sum': 'false', }, }, )
def register_dashboard_items(self): WifiSession = load_model('device_monitoring', 'WifiSession') Chart = load_model('monitoring', 'Chart') register_dashboard_chart( position=0, config={ 'name': _('Monitoring Status'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'monitoring__status', }, 'colors': { 'ok': '#267126', 'problem': '#ffb442', 'critical': '#a72d1d', 'unknown': '#353c44', }, 'labels': { 'ok': app_settings.HEALTH_STATUS_LABELS['ok'], 'problem': app_settings.HEALTH_STATUS_LABELS['problem'], 'critical': app_settings.HEALTH_STATUS_LABELS['critical'], 'unknown': app_settings.HEALTH_STATUS_LABELS['unknown'], }, }, ) if app_settings.DASHBOARD_MAP: loc_geojson_url = reverse_lazy("monitoring:api_location_geojson", urlconf=MONITORING_API_URLCONF) device_list_url = reverse_lazy( "monitoring:api_location_device_list", urlconf=MONITORING_API_URLCONF, args=["000"], ) if MONITORING_API_BASEURL: device_list_url = urljoin(MONITORING_API_BASEURL, str(device_list_url)) loc_geojson_url = urljoin(MONITORING_API_BASEURL, str(loc_geojson_url)) register_dashboard_template( position=0, config={ 'template': 'admin/dashboard/device_map.html', 'css': ( 'monitoring/css/device-map.css', 'leaflet/leaflet.css', 'monitoring/css/leaflet.fullscreen.css', ), 'js': ( 'monitoring/js/device-map.js', 'leaflet/leaflet.js', 'leaflet/leaflet.extras.js', 'monitoring/js/leaflet.fullscreen.min.js', ), }, extra_config={ 'monitoring_device_list_url': device_list_url, 'monitoring_location_geojson_url': loc_geojson_url, }, ) register_dashboard_template( position=55, config={ 'template': 'monitoring/paritals/chart.html', 'css': ( 'monitoring/css/percircle.min.css', 'monitoring/css/chart.css', 'monitoring/css/dashboard-chart.css', ), 'js': ( 'monitoring/js/percircle.min.js', 'monitoring/js/chart.js', 'monitoring/js/chart-utils.js', 'monitoring/js/dashboard-chart.js', ), }, extra_config={ 'api_url': reverse_lazy('monitoring_general:api_dashboard_timeseries'), 'default_time': Chart.DEFAULT_TIME, 'chart_quick_links': { 'General WiFi Clients': { 'url': reverse_lazy( 'admin:{app_label}_{model_name}_changelist'.format( app_label=WifiSession._meta.app_label, model_name=WifiSession._meta.model_name, )), 'label': _('Open WiFi session list'), 'title': _('View full history of WiFi Sessions'), } }, }, after_charts=True, ) if app_settings.WIFI_SESSIONS_ENABLED: register_dashboard_chart( position=13, config={ 'name': _('Currently Active WiFi Sessions'), 'query_params': { 'app_label': WifiSession._meta.app_label, 'model': WifiSession._meta.model_name, 'annotate': { 'active': Count(Case(When( stop_time__isnull=True, then=1, ))), }, 'aggregate': { 'active__sum': Sum('active'), }, }, 'filters': { 'key': 'stop_time__isnull', 'active__sum': 'true', }, 'colors': { 'active__sum': '#267126', }, 'labels': { 'active__sum': _('Currently Active WiFi Sessions'), }, 'quick_link': { 'url': reverse_lazy( 'admin:{app_label}_{model_name}_changelist'.format( app_label=WifiSession._meta.app_label, model_name=WifiSession._meta.model_name, )), 'label': _('Open WiFi session list'), 'title': _('View full history of WiFi Sessions'), 'custom_css_classes': ['negative-top-20'], }, }, )
def register_dashboard_charts(self): register_dashboard_chart( position=0, config={ 'name': _('Operator Project Distribution'), 'query_params': { 'app_label': 'test_project', 'model': 'operator', 'group_by': 'project__name', }, 'colors': {'Utils': 'red', 'User': '******'}, 'labels': {'Utils': _('Utils'), 'User': _('User')}, }, ) register_dashboard_chart( position=1, config={ 'name': _('Operator presence in projects'), 'query_params': { 'app_label': 'test_project', 'model': 'project', 'annotate': { 'with_operator': Count( Case( When( operator__isnull=False, then=1, ) ) ), 'without_operator': Count( Case( When( operator__isnull=True, then=1, ) ) ), }, 'aggregate': { 'with_operator__sum': Sum('with_operator'), 'without_operator__sum': Sum('without_operator'), }, }, 'colors': { 'with_operator__sum': '#267126', 'without_operator__sum': '#353c44', }, 'labels': { 'with_operator__sum': _('Projects with operators'), 'without_operator__sum': _('Projects without operators'), }, 'filters': { 'key': 'with_operator', 'with_operator__sum': 'true', 'without_operator__sum': 'false', }, }, ) register_dashboard_template( position=0, config={ 'template': 'dashboard_test.html', 'css': ('dashboard-test.css',), 'js': ('dashboard-test.js',), }, extra_config={'test_extra_config': 'dashboard-test.config'}, )
def register_dashboard_charts(self): register_dashboard_chart( position=1, config={ 'name': _('Configuration Status'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'config__status', }, 'colors': { 'applied': '#267126', 'modified': '#ffb442', 'error': '#a72d1d', }, 'labels': { 'applied': _('applied'), 'modified': _('modified'), 'error': _('error'), }, }, ) register_dashboard_chart( position=10, config={ 'name': _('Device Models'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'model', }, # since the field can be empty, we need to # define a label and a color for the empty case 'colors': { '': '#353c44' }, 'labels': { '': _('undefined') }, }, ) register_dashboard_chart( position=11, config={ 'name': _('Firmware version'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'os', }, # since the field can be empty, we need to # define a label and a color for the empty case 'colors': { '': '#353c44' }, 'labels': { '': _('undefined') }, }, ) register_dashboard_chart( position=12, config={ 'name': _('System type'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'system', }, # since the field can be empty, we need to # define a label and a color for the empty case 'colors': { '': '#353c44' }, 'labels': { '': _('undefined') }, }, )
def register_dashboard_charts(self): register_dashboard_chart( position=1, config={ 'name': _('Configuration Status'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'config__status', }, 'colors': { 'applied': '#267126', 'modified': '#ffb442', 'error': '#a72d1d', }, 'labels': { 'applied': _('applied'), 'modified': _('modified'), 'error': _('error'), }, }, ) register_dashboard_chart( position=10, config={ 'name': _('Device Models'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'model', }, # since the field can be empty, we need to # define a label and a color for the empty case 'colors': { '': '#353c44' }, 'labels': { '': _('undefined') }, }, ) register_dashboard_chart( position=11, config={ 'name': _('Firmware version'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'os', }, # since the field can be empty, we need to # define a label and a color for the empty case 'colors': { '': '#353c44' }, 'labels': { '': _('undefined') }, }, ) register_dashboard_chart( position=12, config={ 'name': _('System type'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'system', }, # since the field can be empty, we need to # define a label and a color for the empty case 'colors': { '': '#353c44' }, 'labels': { '': _('undefined') }, }, ) if app_settings.GROUP_PIE_CHART: register_dashboard_chart( position=20, config={ 'name': _('Groups'), 'query_params': { 'app_label': 'config', 'model': 'devicegroup', 'annotate': { 'active_count': Count(Case(When( device__isnull=False, then=1, ))), 'empty_count': Count(Case(When( device__isnull=True, then=1, ))), }, 'aggregate': { 'active': Count(Case(When(active_count__gt=0, then=1))), 'empty': Count(Case(When(empty_count__gt=0, then=1))), }, }, 'colors': { 'active': '#2277b4', 'empty': '#EF7D2D', }, 'labels': { 'active': _('Active groups'), 'empty': _('Empty groups'), }, 'filters': { 'key': 'empty', 'active': 'false', 'empty': 'true', }, }, )
def register_dashboard_items(self): register_dashboard_chart( position=0, config={ 'name': _('Monitoring Status'), 'query_params': { 'app_label': 'config', 'model': 'device', 'group_by': 'monitoring__status', }, 'colors': { 'ok': '#267126', 'problem': '#ffb442', 'critical': '#a72d1d', 'unknown': '#353c44', }, 'labels': { 'ok': app_settings.HEALTH_STATUS_LABELS['ok'], 'problem': app_settings.HEALTH_STATUS_LABELS['problem'], 'critical': app_settings.HEALTH_STATUS_LABELS['critical'], 'unknown': app_settings.HEALTH_STATUS_LABELS['unknown'], }, }, ) if app_settings.DASHBOARD_MAP: loc_geojson_url = reverse_lazy("monitoring:api_location_geojson", urlconf=MONITORING_API_URLCONF) device_list_url = reverse_lazy( "monitoring:api_location_device_list", urlconf=MONITORING_API_URLCONF, args=["000"], ) if MONITORING_API_BASEURL: device_list_url = urljoin(MONITORING_API_BASEURL, str(device_list_url)) loc_geojson_url = urljoin(MONITORING_API_BASEURL, str(loc_geojson_url)) register_dashboard_template( position=0, config={ 'template': 'admin/dashboard/device_map.html', 'css': ( 'monitoring/css/device-map.css', 'leaflet/leaflet.css', 'monitoring/css/leaflet.fullscreen.css', ), 'js': ( 'monitoring/js/device-map.js', 'leaflet/leaflet.js', 'leaflet/leaflet.extras.js', 'monitoring/js/leaflet.fullscreen.min.js', ), }, extra_config={ 'monitoring_device_list_url': device_list_url, 'monitoring_location_geojson_url': loc_geojson_url, }, )