DashboardExporter.test.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. jest.mock('app/core/store', () => {
  2. return {
  3. getBool: jest.fn(),
  4. };
  5. });
  6. import _ from 'lodash';
  7. import config from 'app/core/config';
  8. import { DashboardExporter } from './DashboardExporter';
  9. import { DashboardModel } from '../../state/DashboardModel';
  10. import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
  11. import { PanelPluginMeta } from 'app/types';
  12. describe('given dashboard with repeated panels', () => {
  13. let dash: any, exported: any;
  14. beforeEach(done => {
  15. dash = {
  16. templating: {
  17. list: [
  18. {
  19. name: 'apps',
  20. type: 'query',
  21. datasource: 'gfdb',
  22. current: { value: 'Asd', text: 'Asd' },
  23. options: [{ value: 'Asd', text: 'Asd' }],
  24. },
  25. {
  26. name: 'prefix',
  27. type: 'constant',
  28. current: { value: 'collectd', text: 'collectd' },
  29. options: [],
  30. },
  31. {
  32. name: 'ds',
  33. type: 'datasource',
  34. query: 'other2',
  35. current: { value: 'other2', text: 'other2' },
  36. options: [],
  37. },
  38. ],
  39. },
  40. annotations: {
  41. list: [
  42. {
  43. name: 'logs',
  44. datasource: 'gfdb',
  45. },
  46. ],
  47. },
  48. panels: [
  49. { id: 6, datasource: 'gfdb', type: 'graph' },
  50. { id: 7 },
  51. {
  52. id: 8,
  53. datasource: '-- Mixed --',
  54. targets: [{ datasource: 'other' }],
  55. },
  56. { id: 9, datasource: '$ds' },
  57. {
  58. id: 2,
  59. repeat: 'apps',
  60. datasource: 'gfdb',
  61. type: 'graph',
  62. },
  63. { id: 3, repeat: null, repeatPanelId: 2 },
  64. {
  65. id: 4,
  66. collapsed: true,
  67. panels: [
  68. { id: 10, datasource: 'gfdb', type: 'table' },
  69. { id: 11 },
  70. {
  71. id: 12,
  72. datasource: '-- Mixed --',
  73. targets: [{ datasource: 'other' }],
  74. },
  75. { id: 13, datasource: '$ds' },
  76. {
  77. id: 14,
  78. repeat: 'apps',
  79. datasource: 'gfdb',
  80. type: 'heatmap',
  81. },
  82. { id: 15, repeat: null, repeatPanelId: 14 },
  83. ],
  84. },
  85. ],
  86. };
  87. config.buildInfo.version = '3.0.2';
  88. //Stubs test function calls
  89. const datasourceSrvStub = ({ get: jest.fn(arg => getStub(arg)) } as any) as DatasourceSrv;
  90. config.panels['graph'] = {
  91. id: 'graph',
  92. name: 'Graph',
  93. info: { version: '1.1.0' },
  94. } as PanelPluginMeta;
  95. config.panels['table'] = {
  96. id: 'table',
  97. name: 'Table',
  98. info: { version: '1.1.1' },
  99. } as PanelPluginMeta;
  100. config.panels['heatmap'] = {
  101. id: 'heatmap',
  102. name: 'Heatmap',
  103. info: { version: '1.1.2' },
  104. } as PanelPluginMeta;
  105. dash = new DashboardModel(dash, {});
  106. const exporter = new DashboardExporter(datasourceSrvStub);
  107. exporter.makeExportable(dash).then(clean => {
  108. exported = clean;
  109. done();
  110. });
  111. });
  112. it('should replace datasource refs', () => {
  113. const panel = exported.panels[0];
  114. expect(panel.datasource).toBe('${DS_GFDB}');
  115. });
  116. it('should replace datasource refs in collapsed row', () => {
  117. const panel = exported.panels[5].panels[0];
  118. expect(panel.datasource).toBe('${DS_GFDB}');
  119. });
  120. it('should replace datasource in variable query', () => {
  121. expect(exported.templating.list[0].datasource).toBe('${DS_GFDB}');
  122. expect(exported.templating.list[0].options.length).toBe(0);
  123. expect(exported.templating.list[0].current.value).toBe(undefined);
  124. expect(exported.templating.list[0].current.text).toBe(undefined);
  125. });
  126. it('should replace datasource in annotation query', () => {
  127. expect(exported.annotations.list[1].datasource).toBe('${DS_GFDB}');
  128. });
  129. it('should add datasource as input', () => {
  130. expect(exported.__inputs[0].name).toBe('DS_GFDB');
  131. expect(exported.__inputs[0].pluginId).toBe('testdb');
  132. expect(exported.__inputs[0].type).toBe('datasource');
  133. });
  134. it('should add datasource to required', () => {
  135. const require: any = _.find(exported.__requires, { name: 'TestDB' });
  136. expect(require.name).toBe('TestDB');
  137. expect(require.id).toBe('testdb');
  138. expect(require.type).toBe('datasource');
  139. expect(require.version).toBe('1.2.1');
  140. });
  141. it('should not add built in datasources to required', () => {
  142. const require: any = _.find(exported.__requires, { name: 'Mixed' });
  143. expect(require).toBe(undefined);
  144. });
  145. it('should add datasources used in mixed mode', () => {
  146. const require: any = _.find(exported.__requires, { name: 'OtherDB' });
  147. expect(require).not.toBe(undefined);
  148. });
  149. it('should add graph panel to required', () => {
  150. const require: any = _.find(exported.__requires, { name: 'Graph' });
  151. expect(require.name).toBe('Graph');
  152. expect(require.id).toBe('graph');
  153. expect(require.version).toBe('1.1.0');
  154. });
  155. it('should add table panel to required', () => {
  156. const require: any = _.find(exported.__requires, { name: 'Table' });
  157. expect(require.name).toBe('Table');
  158. expect(require.id).toBe('table');
  159. expect(require.version).toBe('1.1.1');
  160. });
  161. it('should add heatmap panel to required', () => {
  162. const require: any = _.find(exported.__requires, { name: 'Heatmap' });
  163. expect(require.name).toBe('Heatmap');
  164. expect(require.id).toBe('heatmap');
  165. expect(require.version).toBe('1.1.2');
  166. });
  167. it('should add grafana version', () => {
  168. const require: any = _.find(exported.__requires, { name: 'Grafana' });
  169. expect(require.type).toBe('grafana');
  170. expect(require.id).toBe('grafana');
  171. expect(require.version).toBe('3.0.2');
  172. });
  173. it('should add constant template variables as inputs', () => {
  174. const input: any = _.find(exported.__inputs, { name: 'VAR_PREFIX' });
  175. expect(input.type).toBe('constant');
  176. expect(input.label).toBe('prefix');
  177. expect(input.value).toBe('collectd');
  178. });
  179. it('should templatize constant variables', () => {
  180. const variable: any = _.find(exported.templating.list, { name: 'prefix' });
  181. expect(variable.query).toBe('${VAR_PREFIX}');
  182. expect(variable.current.text).toBe('${VAR_PREFIX}');
  183. expect(variable.current.value).toBe('${VAR_PREFIX}');
  184. expect(variable.options[0].text).toBe('${VAR_PREFIX}');
  185. expect(variable.options[0].value).toBe('${VAR_PREFIX}');
  186. });
  187. it('should add datasources only use via datasource variable to requires', () => {
  188. const require: any = _.find(exported.__requires, { name: 'OtherDB_2' });
  189. expect(require.id).toBe('other2');
  190. });
  191. });
  192. // Stub responses
  193. const stubs: { [key: string]: {} } = {};
  194. stubs['gfdb'] = {
  195. name: 'gfdb',
  196. meta: { id: 'testdb', info: { version: '1.2.1' }, name: 'TestDB' },
  197. };
  198. stubs['other'] = {
  199. name: 'other',
  200. meta: { id: 'other', info: { version: '1.2.1' }, name: 'OtherDB' },
  201. };
  202. stubs['other2'] = {
  203. name: 'other2',
  204. meta: { id: 'other2', info: { version: '1.2.1' }, name: 'OtherDB_2' },
  205. };
  206. stubs['-- Mixed --'] = {
  207. name: 'mixed',
  208. meta: {
  209. id: 'mixed',
  210. info: { version: '1.2.1' },
  211. name: 'Mixed',
  212. builtIn: true,
  213. },
  214. };
  215. stubs['-- Grafana --'] = {
  216. name: '-- Grafana --',
  217. meta: {
  218. id: 'grafana',
  219. info: { version: '1.2.1' },
  220. name: 'grafana',
  221. builtIn: true,
  222. },
  223. };
  224. function getStub(arg: string) {
  225. return Promise.resolve(stubs[arg || 'gfdb']);
  226. }