manage_dashboards.test.ts 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. // @ts-ignore
  2. import q from 'q';
  3. import {
  4. ManageDashboardsCtrl,
  5. Section,
  6. FoldersAndDashboardUids,
  7. } from 'app/core/components/manage_dashboards/manage_dashboards';
  8. import { SearchSrv } from 'app/core/services/search_srv';
  9. import { BackendSrv } from '../services/backend_srv';
  10. import { NavModelSrv } from '../nav_model_srv';
  11. import { ContextSrv } from '../services/context_srv';
  12. const mockSection = (overides?: object): Section => {
  13. const defaultSection: Section = {
  14. id: 0,
  15. items: [],
  16. checked: false,
  17. expanded: false,
  18. removable: false,
  19. hideHeader: false,
  20. icon: '',
  21. score: 0,
  22. title: 'Some Section',
  23. toggle: jest.fn(),
  24. uid: 'someuid',
  25. url: '/some/url/',
  26. };
  27. return { ...defaultSection, ...overides };
  28. };
  29. describe('ManageDashboards', () => {
  30. let ctrl: ManageDashboardsCtrl;
  31. describe('when browsing dashboards', () => {
  32. beforeEach(() => {
  33. const tags: any[] = [];
  34. const response = [
  35. {
  36. id: 410,
  37. title: 'afolder',
  38. type: 'dash-folder',
  39. items: [
  40. {
  41. id: 399,
  42. title: 'Dashboard Test',
  43. url: 'dashboard/db/dashboard-test',
  44. icon: 'fa fa-folder',
  45. tags,
  46. isStarred: false,
  47. },
  48. ],
  49. tags,
  50. isStarred: false,
  51. },
  52. {
  53. id: 0,
  54. title: 'General',
  55. icon: 'fa fa-folder-open',
  56. uri: 'db/something-else',
  57. type: 'dash-db',
  58. items: [
  59. {
  60. id: 500,
  61. title: 'Dashboard Test',
  62. url: 'dashboard/db/dashboard-test',
  63. icon: 'fa fa-folder',
  64. tags,
  65. isStarred: false,
  66. },
  67. ],
  68. tags,
  69. isStarred: false,
  70. },
  71. ];
  72. ctrl = createCtrlWithStubs(response);
  73. return ctrl.refreshList();
  74. });
  75. it('should set checked to false on all sections and children', () => {
  76. expect(ctrl.sections.length).toEqual(2);
  77. expect(ctrl.sections[0].checked).toEqual(false);
  78. expect(ctrl.sections[0].items[0].checked).toEqual(false);
  79. expect(ctrl.sections[1].checked).toEqual(false);
  80. expect(ctrl.sections[1].items[0].checked).toEqual(false);
  81. expect(ctrl.sections[0].hideHeader).toBeFalsy();
  82. });
  83. });
  84. describe('when browsing dashboards for a folder', () => {
  85. beforeEach(() => {
  86. const tags: any[] = [];
  87. const response = [
  88. {
  89. id: 410,
  90. title: 'afolder',
  91. type: 'dash-folder',
  92. items: [
  93. {
  94. id: 399,
  95. title: 'Dashboard Test',
  96. url: 'dashboard/db/dashboard-test',
  97. icon: 'fa fa-folder',
  98. tags,
  99. isStarred: false,
  100. },
  101. ],
  102. tags,
  103. isStarred: false,
  104. },
  105. ];
  106. ctrl = createCtrlWithStubs(response);
  107. ctrl.folderId = 410;
  108. return ctrl.refreshList();
  109. });
  110. it('should set hide header to true on section', () => {
  111. expect(ctrl.sections[0].hideHeader).toBeTruthy();
  112. });
  113. });
  114. describe('when searching dashboards', () => {
  115. beforeEach(() => {
  116. const tags: any[] = [];
  117. const response = [
  118. {
  119. checked: false,
  120. expanded: true,
  121. hideHeader: true,
  122. items: [
  123. {
  124. id: 399,
  125. title: 'Dashboard Test',
  126. url: 'dashboard/db/dashboard-test',
  127. icon: 'fa fa-folder',
  128. tags,
  129. isStarred: false,
  130. folderId: 410,
  131. folderUid: 'uid',
  132. folderTitle: 'Folder',
  133. folderUrl: '/dashboards/f/uid/folder',
  134. },
  135. {
  136. id: 500,
  137. title: 'Dashboard Test',
  138. url: 'dashboard/db/dashboard-test',
  139. icon: 'fa fa-folder',
  140. tags,
  141. folderId: 499,
  142. isStarred: false,
  143. },
  144. ],
  145. },
  146. ];
  147. ctrl = createCtrlWithStubs(response);
  148. });
  149. describe('with query filter', () => {
  150. beforeEach(() => {
  151. ctrl.query.query = 'd';
  152. ctrl.canMove = true;
  153. ctrl.canDelete = true;
  154. ctrl.selectAllChecked = true;
  155. return ctrl.refreshList();
  156. });
  157. it('should set checked to false on all sections and children', () => {
  158. expect(ctrl.sections.length).toEqual(1);
  159. expect(ctrl.sections[0].checked).toEqual(false);
  160. expect(ctrl.sections[0].items[0].checked).toEqual(false);
  161. expect(ctrl.sections[0].items[1].checked).toEqual(false);
  162. });
  163. it('should uncheck select all', () => {
  164. expect(ctrl.selectAllChecked).toBeFalsy();
  165. });
  166. it('should disable Move To button', () => {
  167. expect(ctrl.canMove).toBeFalsy();
  168. });
  169. it('should disable delete button', () => {
  170. expect(ctrl.canDelete).toBeFalsy();
  171. });
  172. it('should have active filters', () => {
  173. expect(ctrl.hasFilters).toBeTruthy();
  174. });
  175. describe('when select all is checked', () => {
  176. beforeEach(() => {
  177. ctrl.selectAllChecked = true;
  178. ctrl.onSelectAllChanged();
  179. });
  180. it('should select all dashboards', () => {
  181. expect(ctrl.sections[0].checked).toBeFalsy();
  182. expect(ctrl.sections[0].items[0].checked).toBeTruthy();
  183. expect(ctrl.sections[0].items[1].checked).toBeTruthy();
  184. });
  185. it('should enable Move To button', () => {
  186. expect(ctrl.canMove).toBeTruthy();
  187. });
  188. it('should enable delete button', () => {
  189. expect(ctrl.canDelete).toBeTruthy();
  190. });
  191. describe('when clearing filters', () => {
  192. beforeEach(() => {
  193. return ctrl.clearFilters();
  194. });
  195. it('should reset query filter', () => {
  196. expect(ctrl.query.query).toEqual('');
  197. });
  198. });
  199. });
  200. });
  201. describe('with tag filter', () => {
  202. beforeEach(() => {
  203. return ctrl.filterByTag('test');
  204. });
  205. it('should set tag filter', () => {
  206. expect(ctrl.sections.length).toEqual(1);
  207. expect(ctrl.query.tag[0]).toEqual('test');
  208. });
  209. it('should have active filters', () => {
  210. expect(ctrl.hasFilters).toBeTruthy();
  211. });
  212. describe('when clearing filters', () => {
  213. beforeEach(() => {
  214. return ctrl.clearFilters();
  215. });
  216. it('should reset tag filter', () => {
  217. expect(ctrl.query.tag.length).toEqual(0);
  218. });
  219. });
  220. });
  221. describe('with starred filter', () => {
  222. beforeEach(() => {
  223. const yesOption: any = ctrl.starredFilterOptions[1];
  224. ctrl.selectedStarredFilter = yesOption;
  225. return ctrl.onStarredFilterChange();
  226. });
  227. it('should set starred filter', () => {
  228. expect(ctrl.sections.length).toEqual(1);
  229. expect(ctrl.query.starred).toEqual(true);
  230. });
  231. it('should have active filters', () => {
  232. expect(ctrl.hasFilters).toBeTruthy();
  233. });
  234. describe('when clearing filters', () => {
  235. beforeEach(() => {
  236. return ctrl.clearFilters();
  237. });
  238. it('should reset starred filter', () => {
  239. expect(ctrl.query.starred).toEqual(false);
  240. });
  241. });
  242. });
  243. });
  244. describe('when selecting dashboards', () => {
  245. let ctrl: ManageDashboardsCtrl;
  246. beforeEach(() => {
  247. ctrl = createCtrlWithStubs([]);
  248. });
  249. describe('and no dashboards are selected', () => {
  250. beforeEach(() => {
  251. ctrl.sections = [
  252. mockSection({
  253. id: 1,
  254. items: [{ id: 2, checked: false }],
  255. checked: false,
  256. }),
  257. mockSection({
  258. id: 0,
  259. items: [{ id: 3, checked: false }],
  260. checked: false,
  261. }),
  262. ];
  263. ctrl.selectionChanged();
  264. });
  265. it('should disable Move To button', () => {
  266. expect(ctrl.canMove).toBeFalsy();
  267. });
  268. it('should disable delete button', () => {
  269. expect(ctrl.canDelete).toBeFalsy();
  270. });
  271. describe('when select all is checked', () => {
  272. beforeEach(() => {
  273. ctrl.selectAllChecked = true;
  274. ctrl.onSelectAllChanged();
  275. });
  276. it('should select all folders and dashboards', () => {
  277. expect(ctrl.sections[0].checked).toBeTruthy();
  278. expect(ctrl.sections[0].items[0].checked).toBeTruthy();
  279. expect(ctrl.sections[1].checked).toBeTruthy();
  280. expect(ctrl.sections[1].items[0].checked).toBeTruthy();
  281. });
  282. it('should enable Move To button', () => {
  283. expect(ctrl.canMove).toBeTruthy();
  284. });
  285. it('should enable delete button', () => {
  286. expect(ctrl.canDelete).toBeTruthy();
  287. });
  288. });
  289. });
  290. describe('and all folders and dashboards are selected', () => {
  291. beforeEach(() => {
  292. ctrl.sections = [
  293. mockSection({
  294. id: 1,
  295. items: [{ id: 2, checked: true }],
  296. checked: true,
  297. }),
  298. mockSection({
  299. id: 0,
  300. items: [{ id: 3, checked: true }],
  301. checked: true,
  302. }),
  303. ];
  304. ctrl.selectionChanged();
  305. });
  306. it('should enable Move To button', () => {
  307. expect(ctrl.canMove).toBeTruthy();
  308. });
  309. it('should enable delete button', () => {
  310. expect(ctrl.canDelete).toBeTruthy();
  311. });
  312. describe('when select all is unchecked', () => {
  313. beforeEach(() => {
  314. ctrl.selectAllChecked = false;
  315. ctrl.onSelectAllChanged();
  316. });
  317. it('should uncheck all checked folders and dashboards', () => {
  318. expect(ctrl.sections[0].checked).toBeFalsy();
  319. expect(ctrl.sections[0].items[0].checked).toBeFalsy();
  320. expect(ctrl.sections[1].checked).toBeFalsy();
  321. expect(ctrl.sections[1].items[0].checked).toBeFalsy();
  322. });
  323. it('should disable Move To button', () => {
  324. expect(ctrl.canMove).toBeFalsy();
  325. });
  326. it('should disable delete button', () => {
  327. expect(ctrl.canDelete).toBeFalsy();
  328. });
  329. });
  330. });
  331. describe('and one dashboard in root is selected', () => {
  332. beforeEach(() => {
  333. ctrl.sections = [
  334. mockSection({
  335. id: 1,
  336. title: 'folder',
  337. items: [{ id: 2, checked: false }],
  338. checked: false,
  339. }),
  340. mockSection({
  341. id: 0,
  342. title: 'General',
  343. items: [{ id: 3, checked: true }],
  344. checked: false,
  345. }),
  346. ];
  347. ctrl.selectionChanged();
  348. });
  349. it('should enable Move To button', () => {
  350. expect(ctrl.canMove).toBeTruthy();
  351. });
  352. it('should enable delete button', () => {
  353. expect(ctrl.canDelete).toBeTruthy();
  354. });
  355. });
  356. describe('and one child dashboard is selected', () => {
  357. beforeEach(() => {
  358. ctrl.sections = [
  359. mockSection({
  360. id: 1,
  361. title: 'folder',
  362. items: [{ id: 2, checked: true }],
  363. checked: false,
  364. }),
  365. mockSection({
  366. id: 0,
  367. title: 'General',
  368. items: [{ id: 3, checked: false }],
  369. checked: false,
  370. }),
  371. ];
  372. ctrl.selectionChanged();
  373. });
  374. it('should enable Move To button', () => {
  375. expect(ctrl.canMove).toBeTruthy();
  376. });
  377. it('should enable delete button', () => {
  378. expect(ctrl.canDelete).toBeTruthy();
  379. });
  380. });
  381. describe('and one child dashboard and one dashboard is selected', () => {
  382. beforeEach(() => {
  383. ctrl.sections = [
  384. mockSection({
  385. id: 1,
  386. title: 'folder',
  387. items: [{ id: 2, checked: true }],
  388. checked: false,
  389. }),
  390. mockSection({
  391. id: 0,
  392. title: 'General',
  393. items: [{ id: 3, checked: true }],
  394. checked: false,
  395. }),
  396. ];
  397. ctrl.selectionChanged();
  398. });
  399. it('should enable Move To button', () => {
  400. expect(ctrl.canMove).toBeTruthy();
  401. });
  402. it('should enable delete button', () => {
  403. expect(ctrl.canDelete).toBeTruthy();
  404. });
  405. });
  406. describe('and one child dashboard and one folder is selected', () => {
  407. beforeEach(() => {
  408. ctrl.sections = [
  409. mockSection({
  410. id: 1,
  411. title: 'folder',
  412. items: [{ id: 2, checked: false }],
  413. checked: true,
  414. }),
  415. mockSection({
  416. id: 3,
  417. title: 'folder',
  418. items: [{ id: 4, checked: true }],
  419. checked: false,
  420. }),
  421. mockSection({
  422. id: 0,
  423. title: 'General',
  424. items: [{ id: 3, checked: false }],
  425. checked: false,
  426. }),
  427. ];
  428. ctrl.selectionChanged();
  429. });
  430. it('should enable Move To button', () => {
  431. expect(ctrl.canMove).toBeTruthy();
  432. });
  433. it('should enable delete button', () => {
  434. expect(ctrl.canDelete).toBeTruthy();
  435. });
  436. });
  437. });
  438. describe('when deleting dashboards', () => {
  439. let toBeDeleted: FoldersAndDashboardUids;
  440. beforeEach(() => {
  441. ctrl = createCtrlWithStubs([]);
  442. ctrl.sections = [
  443. mockSection({
  444. id: 1,
  445. uid: 'folder',
  446. title: 'folder',
  447. items: [{ id: 2, checked: true, uid: 'folder-dash' }],
  448. checked: true,
  449. }),
  450. mockSection({
  451. id: 3,
  452. title: 'folder-2',
  453. items: [{ id: 3, checked: true, uid: 'folder-2-dash' }],
  454. checked: false,
  455. uid: 'folder-2',
  456. }),
  457. mockSection({
  458. id: 0,
  459. title: 'General',
  460. items: [{ id: 3, checked: true, uid: 'root-dash' }],
  461. checked: true,
  462. }),
  463. ];
  464. toBeDeleted = ctrl.getFoldersAndDashboardsToDelete();
  465. });
  466. it('should return 1 folder', () => {
  467. expect(toBeDeleted.folderUids.length).toEqual(1);
  468. });
  469. it('should return 2 dashboards', () => {
  470. expect(toBeDeleted.dashboardUids.length).toEqual(2);
  471. });
  472. it('should filter out children if parent is checked', () => {
  473. expect(toBeDeleted.folderUids[0]).toEqual('folder');
  474. });
  475. it('should not filter out children if parent not is checked', () => {
  476. expect(toBeDeleted.dashboardUids[0]).toEqual('folder-2-dash');
  477. });
  478. it('should not filter out children if parent is checked and root', () => {
  479. expect(toBeDeleted.dashboardUids[1]).toEqual('root-dash');
  480. });
  481. });
  482. describe('when moving dashboards', () => {
  483. beforeEach(() => {
  484. ctrl = createCtrlWithStubs([]);
  485. ctrl.sections = [
  486. mockSection({
  487. id: 1,
  488. title: 'folder',
  489. items: [{ id: 2, checked: true, uid: 'dash' }],
  490. checked: false,
  491. uid: 'folder',
  492. }),
  493. mockSection({
  494. id: 0,
  495. title: 'General',
  496. items: [{ id: 3, checked: true, uid: 'dash-2' }],
  497. checked: false,
  498. }),
  499. ];
  500. });
  501. it('should get selected dashboards', () => {
  502. const toBeMove = ctrl.getDashboardsToMove();
  503. expect(toBeMove.length).toEqual(2);
  504. expect(toBeMove[0]).toEqual('dash');
  505. expect(toBeMove[1]).toEqual('dash-2');
  506. });
  507. });
  508. });
  509. function createCtrlWithStubs(searchResponse: any, tags?: any) {
  510. const searchSrvStub = {
  511. search: (options: any) => {
  512. return q.resolve(searchResponse);
  513. },
  514. getDashboardTags: () => {
  515. return q.resolve(tags || []);
  516. },
  517. };
  518. return new ManageDashboardsCtrl(
  519. {} as BackendSrv,
  520. { getNav: () => {} } as NavModelSrv,
  521. searchSrvStub as SearchSrv,
  522. { isEditor: true } as ContextSrv
  523. );
  524. }