From 35694a76efbff0ebff57c1af7c6ecbc0a8365fc2 Mon Sep 17 00:00:00 2001 From: Tobias Skarhed Date: Wed, 1 Aug 2018 17:11:29 +0200 Subject: [PATCH] Class to function. Half tests passing --- .../app/features/dashboard/shareModalCtrl.ts | 180 +++++++++--------- .../dashboard/specs/share_modal_ctrl.jest.ts | 154 +++++++++++++++ 2 files changed, 243 insertions(+), 91 deletions(-) create mode 100644 public/app/features/dashboard/specs/share_modal_ctrl.jest.ts diff --git a/public/app/features/dashboard/shareModalCtrl.ts b/public/app/features/dashboard/shareModalCtrl.ts index 985c20f03b2..c32c2a79190 100644 --- a/public/app/features/dashboard/shareModalCtrl.ts +++ b/public/app/features/dashboard/shareModalCtrl.ts @@ -2,120 +2,118 @@ import angular from 'angular'; import config from 'app/core/config'; import moment from 'moment'; -export class ShareModalCtrl { - /** @ngInject */ - constructor($scope, $rootScope, $location, $timeout, timeSrv, templateSrv, linkSrv) { - $scope.options = { - forCurrent: true, - includeTemplateVars: true, - theme: 'current', - }; - $scope.editor = { index: $scope.tabIndex || 0 }; +/** @ngInject */ +export function ShareModalCtrl($scope, $rootScope, $location, $timeout, timeSrv, templateSrv, linkSrv) { + $scope.options = { + forCurrent: true, + includeTemplateVars: true, + theme: 'current', + }; + $scope.editor = { index: $scope.tabIndex || 0 }; - $scope.init = function() { - $scope.modeSharePanel = $scope.panel ? true : false; + $scope.init = function() { + $scope.modeSharePanel = $scope.panel ? true : false; - $scope.tabs = [{ title: 'Link', src: 'shareLink.html' }]; + $scope.tabs = [{ title: 'Link', src: 'shareLink.html' }]; - if ($scope.modeSharePanel) { - $scope.modalTitle = 'Share Panel'; - $scope.tabs.push({ title: 'Embed', src: 'shareEmbed.html' }); - } else { - $scope.modalTitle = 'Share'; - } + if ($scope.modeSharePanel) { + $scope.modalTitle = 'Share Panel'; + $scope.tabs.push({ title: 'Embed', src: 'shareEmbed.html' }); + } else { + $scope.modalTitle = 'Share'; + } - if (!$scope.dashboard.meta.isSnapshot) { - $scope.tabs.push({ title: 'Snapshot', src: 'shareSnapshot.html' }); - } + if (!$scope.dashboard.meta.isSnapshot) { + $scope.tabs.push({ title: 'Snapshot', src: 'shareSnapshot.html' }); + } - if (!$scope.dashboard.meta.isSnapshot && !$scope.modeSharePanel) { - $scope.tabs.push({ title: 'Export', src: 'shareExport.html' }); - } + if (!$scope.dashboard.meta.isSnapshot && !$scope.modeSharePanel) { + $scope.tabs.push({ title: 'Export', src: 'shareExport.html' }); + } - $scope.buildUrl(); - }; + $scope.buildUrl(); + }; - $scope.buildUrl = function() { - var baseUrl = $location.absUrl(); - var queryStart = baseUrl.indexOf('?'); + $scope.buildUrl = function() { + var baseUrl = $location.absUrl(); + var queryStart = baseUrl.indexOf('?'); - if (queryStart !== -1) { - baseUrl = baseUrl.substring(0, queryStart); - } + if (queryStart !== -1) { + baseUrl = baseUrl.substring(0, queryStart); + } - var params = angular.copy($location.search()); + var params = angular.copy($location.search()); - var range = timeSrv.timeRange(); - params.from = range.from.valueOf(); - params.to = range.to.valueOf(); - params.orgId = config.bootData.user.orgId; + var range = timeSrv.timeRange(); + params.from = range.from.valueOf(); + params.to = range.to.valueOf(); + params.orgId = config.bootData.user.orgId; - if ($scope.options.includeTemplateVars) { - templateSrv.fillVariableValuesForUrl(params); - } + if ($scope.options.includeTemplateVars) { + templateSrv.fillVariableValuesForUrl(params); + } - if (!$scope.options.forCurrent) { - delete params.from; - delete params.to; - } + if (!$scope.options.forCurrent) { + delete params.from; + delete params.to; + } - if ($scope.options.theme !== 'current') { - params.theme = $scope.options.theme; - } + if ($scope.options.theme !== 'current') { + params.theme = $scope.options.theme; + } - if ($scope.modeSharePanel) { - params.panelId = $scope.panel.id; - params.fullscreen = true; - } else { - delete params.panelId; - delete params.fullscreen; - } - - $scope.shareUrl = linkSrv.addParamsToUrl(baseUrl, params); - - var soloUrl = baseUrl.replace(config.appSubUrl + '/dashboard/', config.appSubUrl + '/dashboard-solo/'); - soloUrl = soloUrl.replace(config.appSubUrl + '/d/', config.appSubUrl + '/d-solo/'); + if ($scope.modeSharePanel) { + params.panelId = $scope.panel.id; + params.fullscreen = true; + } else { + delete params.panelId; delete params.fullscreen; - delete params.edit; - soloUrl = linkSrv.addParamsToUrl(soloUrl, params); + } - $scope.iframeHtml = ''; + $scope.shareUrl = linkSrv.addParamsToUrl(baseUrl, params); - $scope.imageUrl = soloUrl.replace( - config.appSubUrl + '/dashboard-solo/', - config.appSubUrl + '/render/dashboard-solo/' - ); - $scope.imageUrl = $scope.imageUrl.replace(config.appSubUrl + '/d-solo/', config.appSubUrl + '/render/d-solo/'); - $scope.imageUrl += '&width=1000&height=500' + $scope.getLocalTimeZone(); - }; + var soloUrl = baseUrl.replace(config.appSubUrl + '/dashboard/', config.appSubUrl + '/dashboard-solo/'); + soloUrl = soloUrl.replace(config.appSubUrl + '/d/', config.appSubUrl + '/d-solo/'); + delete params.fullscreen; + delete params.edit; + soloUrl = linkSrv.addParamsToUrl(soloUrl, params); - // This function will try to return the proper full name of the local timezone - // Chrome does not handle the timezone offset (but phantomjs does) - $scope.getLocalTimeZone = function() { - let utcOffset = '&tz=UTC' + encodeURIComponent(moment().format('Z')); + $scope.iframeHtml = ''; - // Older browser does not the internationalization API - if (!(window).Intl) { - return utcOffset; - } + $scope.imageUrl = soloUrl.replace( + config.appSubUrl + '/dashboard-solo/', + config.appSubUrl + '/render/dashboard-solo/' + ); + $scope.imageUrl = $scope.imageUrl.replace(config.appSubUrl + '/d-solo/', config.appSubUrl + '/render/d-solo/'); + $scope.imageUrl += '&width=1000&height=500' + $scope.getLocalTimeZone(); + }; - const dateFormat = (window).Intl.DateTimeFormat(); - if (!dateFormat.resolvedOptions) { - return utcOffset; - } + // This function will try to return the proper full name of the local timezone + // Chrome does not handle the timezone offset (but phantomjs does) + $scope.getLocalTimeZone = function() { + let utcOffset = '&tz=UTC' + encodeURIComponent(moment().format('Z')); - const options = dateFormat.resolvedOptions(); - if (!options.timeZone) { - return utcOffset; - } + // Older browser does not the internationalization API + if (!(window).Intl) { + return utcOffset; + } - return '&tz=' + encodeURIComponent(options.timeZone); - }; + const dateFormat = (window).Intl.DateTimeFormat(); + if (!dateFormat.resolvedOptions) { + return utcOffset; + } - $scope.getShareUrl = function() { - return $scope.shareUrl; - }; - } + const options = dateFormat.resolvedOptions(); + if (!options.timeZone) { + return utcOffset; + } + + return '&tz=' + encodeURIComponent(options.timeZone); + }; + + $scope.getShareUrl = function() { + return $scope.shareUrl; + }; } angular.module('grafana.controllers').controller('ShareModalCtrl', ShareModalCtrl); diff --git a/public/app/features/dashboard/specs/share_modal_ctrl.jest.ts b/public/app/features/dashboard/specs/share_modal_ctrl.jest.ts new file mode 100644 index 00000000000..47b2a2189cd --- /dev/null +++ b/public/app/features/dashboard/specs/share_modal_ctrl.jest.ts @@ -0,0 +1,154 @@ +import '../shareModalCtrl'; +import { ShareModalCtrl } from '../shareModalCtrl'; +import config from 'app/core/config'; +import { LinkSrv } from 'app/features/panellinks/link_srv'; + +describe('ShareModalCtrl', () => { + var ctx = { + timeSrv: { + timeRange: () => { + return { from: new Date(1000), to: new Date(2000) }; + }, + }, + $location: { + absUrl: () => 'http://server/#!/test', + search: () => { + return { from: '', to: '' }; + }, + }, + scope: { + dashboard: { + meta: { + isSnapshot: true, + }, + }, + }, + templateSrv: { + fillVariableValuesForUrl: () => {}, + }, + }; + // function setTime(range) { + // ctx.timeSrv.timeRange = () => range; + // } + + beforeEach(() => { + config.bootData = { + user: { + orgId: 1, + }, + }; + }); + + // setTime({ from: new Date(1000), to: new Date(2000) }); + + // beforeEach(angularMocks.module('grafana.controllers')); + // beforeEach(angularMocks.module('grafana.services')); + // beforeEach( + // angularMocks.module(function($compileProvider) { + // $compileProvider.preAssignBindingsEnabled(true); + // }) + // ); + + // beforeEach(ctx.providePhase()); + + // beforeEach(ctx.createControllerPhase('ShareModalCtrl')); + beforeEach(() => { + ctx.ctrl = new ShareModalCtrl( + ctx.scope, + {}, + ctx.$location, + {}, + ctx.timeSrv, + ctx.templateSrv, + new LinkSrv({}, ctx.stimeSrv) + ); + }); + + describe('shareUrl with current time range and panel', () => { + it('should generate share url absolute time', () => { + // ctx.$location.path('/test'); + ctx.scope.panel = { id: 22 }; + + ctx.scope.init(); + expect(ctx.scope.shareUrl).toBe('http://server/#!/test?from=1000&to=2000&orgId=1&panelId=22&fullscreen'); + }); + + it('should generate render url', () => { + ctx.$location.absUrl = () => 'http://dashboards.grafana.com/d/abcdefghi/my-dash'; + + ctx.scope.panel = { id: 22 }; + + ctx.scope.init(); + var base = 'http://dashboards.grafana.com/render/d-solo/abcdefghi/my-dash'; + var params = '?from=1000&to=2000&orgId=1&panelId=22&width=1000&height=500&tz=UTC'; + expect(ctx.scope.imageUrl).toContain(base + params); + }); + + it('should generate render url for scripted dashboard', () => { + ctx.$location.absUrl = () => 'http://dashboards.grafana.com/dashboard/script/my-dash.js'; + + ctx.scope.panel = { id: 22 }; + + ctx.scope.init(); + var base = 'http://dashboards.grafana.com/render/dashboard-solo/script/my-dash.js'; + var params = '?from=1000&to=2000&orgId=1&panelId=22&width=1000&height=500&tz=UTC'; + expect(ctx.scope.imageUrl).toContain(base + params); + }); + + it('should remove panel id when no panel in scope', () => { + // ctx.$location.path('/test'); + ctx.$location.absUrl = () => 'http://server/#!/test'; + ctx.scope.options.forCurrent = true; + ctx.scope.panel = null; + + ctx.scope.init(); + expect(ctx.scope.shareUrl).toBe('http://server/#!/test?from=1000&to=2000&orgId=1'); + }); + + it('should add theme when specified', () => { + // ctx.$location.path('/test'); + ctx.scope.options.theme = 'light'; + ctx.scope.panel = null; + + ctx.scope.init(); + expect(ctx.scope.shareUrl).toBe('http://server/#!/test?from=1000&to=2000&orgId=1&theme=light'); + }); + + it('should remove fullscreen from image url when is first param in querystring and modeSharePanel is true', () => { + ctx.$location.absUrl = () => 'http://server/#!/test?fullscreen&edit'; + ctx.scope.modeSharePanel = true; + ctx.scope.panel = { id: 1 }; + + ctx.scope.buildUrl(); + + expect(ctx.scope.shareUrl).toContain('?fullscreen&edit&from=1000&to=2000&orgId=1&panelId=1'); + expect(ctx.scope.imageUrl).toContain('?from=1000&to=2000&orgId=1&panelId=1&width=1000&height=500&tz=UTC'); + }); + + it('should remove edit from image url when is first param in querystring and modeSharePanel is true', () => { + ctx.$location.absUrl = () => 'http://server/#!/test?edit&fullscreen'; + ctx.scope.modeSharePanel = true; + ctx.scope.panel = { id: 1 }; + + ctx.scope.buildUrl(); + + expect(ctx.scope.shareUrl).toContain('?edit&fullscreen&from=1000&to=2000&orgId=1&panelId=1'); + expect(ctx.scope.imageUrl).toContain('?from=1000&to=2000&orgId=1&panelId=1&width=1000&height=500&tz=UTC'); + }); + + it('should include template variables in url', () => { + ctx.$location.absUrl = () => 'http://server/#!/test'; + ctx.scope.options.includeTemplateVars = true; + + ctx.templateSrv.fillVariableValuesForUrl = function(params) { + params['var-app'] = 'mupp'; + params['var-server'] = 'srv-01'; + }; + + ctx.scope.buildUrl(); + expect(ctx.scope.shareUrl).toContain( + 'http://server/#!/test?from=1000&to=2000&orgId=1&var-app=mupp&var-server=srv-01' + ); + }); + }); +});