navigation.test.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. import Nav from '../index';
  2. import { clear } from 'jest-date-mock';
  3. import { genBeforeEach, genAfterEach, mount } from '@douyinfe/semi-ui/_test_/utils/tooltip';
  4. import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
  5. import { noop } from 'lodash';
  6. describe(`Navigation`, () => {
  7. beforeEach(() => {
  8. clear();
  9. genBeforeEach()();
  10. });
  11. afterEach(genAfterEach());
  12. it(`test appearance`, async () => {
  13. const items = [
  14. { itemKey: 'user', text: '用户管理' },
  15. { itemKey: 'union', text: '公会中心' },
  16. {
  17. itemKey: 'union-management',
  18. text: '公会管理',
  19. items: ['公告设置', '公会查询', '信息录入'],
  20. },
  21. {
  22. text: '任务平台',
  23. itemKey: 'job',
  24. items: ['任务管理', '用户任务查询'],
  25. },
  26. ];
  27. const nav = mount(
  28. <Nav
  29. defaultOpenKeys={['job']}
  30. bodyStyle={{ height: 320 }}
  31. items={items}
  32. onSelect={key => console.log(key)}
  33. header={{
  34. logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwzthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
  35. text: 'Semi 运营后台',
  36. }}
  37. footer={{
  38. collapseButton: true,
  39. }}
  40. />
  41. );
  42. // check if has header logo
  43. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-header-logo`).length > 0).toBeTruthy();
  44. // check if has header text
  45. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-header-text`).length > 0).toBeTruthy();
  46. // check if has opened sub navigation
  47. expect(
  48. document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-item-sub .${BASE_CLASS_PREFIX}-navigation-sub-open`).length > 0
  49. ).toBeTruthy();
  50. // check if has correct navigation items
  51. expect(
  52. document.querySelector(`.${BASE_CLASS_PREFIX}-navigation .${BASE_CLASS_PREFIX}-navigation-list`).children.length === items.length
  53. ).toBeTruthy();
  54. // check if has correct collapsed button
  55. expect(
  56. document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-footer .${BASE_CLASS_PREFIX}-navigation-collapse-btn`).length > 0
  57. ).toBeTruthy();
  58. });
  59. it(`test appearance with jsx definitions`, async () => {
  60. const defaultOpenKeys = ['user'];
  61. const nav = mount(
  62. <Nav
  63. bodyStyle={{ height: 320 }}
  64. defaultOpenKeys={defaultOpenKeys}
  65. onSelect={data => console.log('trigger onSelect: ', data)}
  66. onClick={data => console.log('trigger onClick: ', data)}
  67. >
  68. <Nav.Header logo={'bytedance_logo'} text={'Semi 运营后台'} />
  69. <Nav.Item itemKey={'union'} text={'公会中心'} icon={'star'} />
  70. <Nav.Sub itemKey={'user'} text="用户管理" icon="user">
  71. <Nav.Item itemKey={'golder'} text={'金主管理'} />
  72. <Nav.Item itemKey={'ban'} text={'用户封禁'} />
  73. </Nav.Sub>
  74. <Nav.Sub itemKey={'union-management'} text="公会管理" icon="user_group">
  75. <Nav.Item itemKey={'notice'} text={'公告设置'} />
  76. <Nav.Item itemKey={'query'} text={'公会查询'} />
  77. <Nav.Item itemKey={'info'} text={'信息录入'} />
  78. </Nav.Sub>
  79. <Nav.Footer collapseButton={true} />
  80. </Nav>
  81. );
  82. // check if has header logo
  83. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-header-logo`).length > 0).toBeTruthy();
  84. // check if has header text
  85. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-header-text`).length > 0).toBeTruthy();
  86. // check if has opened sub navigation
  87. expect(
  88. document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-item-sub .${BASE_CLASS_PREFIX}-navigation-sub-open`).length > 0
  89. ).toBeTruthy();
  90. // check if has correct navigation items
  91. expect(document.querySelector(`.${BASE_CLASS_PREFIX}-navigation .${BASE_CLASS_PREFIX}-navigation-list`).children.length === 3).toBeTruthy();
  92. // check if has correct collapsed button
  93. expect(
  94. document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-footer .${BASE_CLASS_PREFIX}-navigation-collapse-btn`).length > 0
  95. ).toBeTruthy();
  96. });
  97. it(`test horizontal nav appearance`, async () => {
  98. const onSelect = sinon.spy();
  99. const onClick = sinon.spy();
  100. const items = [
  101. { itemKey: 'user', text: '用户管理' },
  102. { itemKey: 'union', text: '公会中心' },
  103. {
  104. itemKey: 'approve-management',
  105. text: '审批管理',
  106. items: [
  107. '入驻审核',
  108. {
  109. itemKey: 'operation-management',
  110. text: '运营管理',
  111. items: ['人员管理', '人员变更'],
  112. },
  113. ],
  114. },
  115. {
  116. text: '任务平台',
  117. itemKey: 'job',
  118. items: ['任务管理', '用户任务查询'],
  119. },
  120. ];
  121. const nav = mount(
  122. <Nav
  123. mode={'horizontal'}
  124. onSelect={onSelect}
  125. onClick={onClick}
  126. items={items}
  127. header={{
  128. logo: 'bytedance_logo',
  129. text: 'Semi 运营后台',
  130. }}
  131. footer={{ collapseButton: true }}
  132. />
  133. );
  134. // check if has header logo
  135. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-header-logo`).length > 0).toBeTruthy();
  136. // check if has header text
  137. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-header-text`).length > 0).toBeTruthy();
  138. // check if has opened sub navigation
  139. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-item-sub`).length > 0).toBeTruthy();
  140. // check if has correct navigation items
  141. expect(
  142. document.querySelector(`.${BASE_CLASS_PREFIX}-navigation .${BASE_CLASS_PREFIX}-navigation-list`).children.length === items.length
  143. ).toBeTruthy();
  144. // check if has correct collapsed button
  145. expect(
  146. document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-footer .${BASE_CLASS_PREFIX}-navigation-collapse-btn`).length === 0
  147. ).toBeTruthy();
  148. });
  149. it(`test controlled selected and open`, async () => {
  150. const items = [
  151. { itemKey: 'user', text: '用户管理', icon: 'user' },
  152. { itemKey: 'union', text: '公会中心', icon: 'star' },
  153. {
  154. itemKey: 'union-management',
  155. text: '公会管理',
  156. icon: 'user_group',
  157. items: ['公告设置', '公会查询', '信息录入'],
  158. },
  159. {
  160. text: '任务平台',
  161. icon: 'setting',
  162. itemKey: 'job',
  163. items: ['任务管理', '用户任务查询'],
  164. },
  165. ];
  166. const openKeys = ['union-management', 'job'];
  167. const selectedKeys = ['用户任务查询'];
  168. const isCollapsed = false;
  169. const onSelect = sinon.spy(({ selectedKeys }) =>
  170. nav.setProps({
  171. selectedKeys,
  172. })
  173. );
  174. const onOpenChange = sinon.spy(({ openKeys }) => nav.setProps({ openKeys }));
  175. const onCollapseChange = sinon.spy(isCollapsed => nav.setProps({ isCollapsed }));
  176. const onClick = sinon.spy(() => {});
  177. const nav = mount(
  178. <Nav
  179. openKeys={openKeys}
  180. bodyStyle={{ height: 320 }}
  181. items={items}
  182. onOpenChange={onOpenChange}
  183. selectedKeys={selectedKeys}
  184. onSelect={onSelect}
  185. isCollapsed={isCollapsed}
  186. onCollapseChange={onCollapseChange}
  187. onClick={onClick}
  188. header={{
  189. logo: <img src="https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwzthlaukjlkulzlp/root-web-sites/webcast_logo.svg" />,
  190. text: 'Semi 运营后台',
  191. }}
  192. footer={{
  193. collapseButton: true,
  194. }}
  195. />
  196. );
  197. // close first opened navigation list
  198. document.querySelector(`.${BASE_CLASS_PREFIX}-navigation-sub-title`).click();
  199. expect(onOpenChange.called).toBeTruthy();
  200. expect(nav.prop('openKeys').length === openKeys.length - 1).toBeTruthy();
  201. // select first opened sub menu list's first item
  202. document.querySelector(`.${BASE_CLASS_PREFIX}-navigation-sub-open`).children[0].click();
  203. expect(onSelect.called).toBeTruthy();
  204. expect(nav.prop('selectedKeys').length === 1).toBeTruthy();
  205. // click collpase button
  206. document.querySelector(`.${BASE_CLASS_PREFIX}-navigation-collapse-btn button`).click();
  207. expect(onCollapseChange.called).toBeTruthy();
  208. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-collapsed`).length === 1).toBeTruthy();
  209. });
  210. it(`test function call parameter`, async () => {
  211. const onSelect = sinon.spy(noop);
  212. const onOpenChange = sinon.spy(noop);
  213. const onCollapseChange = sinon.spy(noop);
  214. const onClick = sinon.spy(noop);
  215. const nav = mount(
  216. <Nav
  217. bodyStyle={{ height: 320 }}
  218. items={[
  219. { itemKey: 'user', text: '用户管理', icon: 'user' },
  220. { itemKey: 'union', text: '公会中心', icon: 'star' },
  221. {
  222. text: '任务平台',
  223. icon: 'setting',
  224. itemKey: 'job',
  225. items: ['任务管理', '用户任务查询'],
  226. },
  227. ]}
  228. onSelect={onSelect}
  229. onOpenChange={onOpenChange}
  230. onCollapseChange={onCollapseChange}
  231. onClick={onClick}
  232. footer={{
  233. collapseButton: true,
  234. }}
  235. />
  236. );
  237. const subTitle = nav.find(`.${BASE_CLASS_PREFIX}-navigation-sub-title`);
  238. subTitle.simulate('click');
  239. expect(onClick.called).toBeTruthy();
  240. expect(onOpenChange.called).toBeTruthy();
  241. expect(onClick.getCall(0).args[0].itemKey).toEqual('job');
  242. expect(onOpenChange.getCall(0).args[0].itemKey).toEqual('job');
  243. const firstItem = nav.find(`.${BASE_CLASS_PREFIX}-navigation-item`).at(0);
  244. firstItem.simulate('click');
  245. expect(onSelect.called).toBeTruthy();
  246. expect(onSelect.getCall(0).args[0].itemKey).toEqual('user');
  247. const collpaseBtn = nav.find(`.${BASE_CLASS_PREFIX}-navigation-collapse-btn button`).at(0);
  248. collpaseBtn.simulate('click');
  249. expect(onCollapseChange.called).toBeTruthy();
  250. expect(onCollapseChange.getCall(0).args[0]).toEqual(true);
  251. });
  252. it(`test itemKey is a number type expansion`, async () => {
  253. const onSelect = sinon.spy(noop);
  254. const onOpenChange = sinon.spy(noop);
  255. const onCollapseChange = sinon.spy(noop);
  256. const onClick = sinon.spy(noop);
  257. const nav = mount(
  258. <Nav
  259. bodyStyle={{ height: 320 }}
  260. items={[
  261. { itemKey: 'user', text: '用户管理', icon: 'user' },
  262. { itemKey: 'union', text: '公会中心', icon: 'star' },
  263. {
  264. text: '任务平台',
  265. icon: 'setting',
  266. itemKey: 2,
  267. items: ['任务管理', '用户任务查询'],
  268. },
  269. ]}
  270. onSelect={onSelect}
  271. onOpenChange={onOpenChange}
  272. onCollapseChange={onCollapseChange}
  273. onClick={onClick}
  274. footer={{
  275. collapseButton: true,
  276. }}
  277. />
  278. );
  279. const subTitle = nav.find(`.${BASE_CLASS_PREFIX}-navigation-sub-title`);
  280. subTitle.simulate('click');
  281. expect(onClick.called).toBeTruthy();
  282. expect(onOpenChange.called).toBeTruthy();
  283. expect(onClick.getCall(0).args[0].itemKey).toEqual(2);
  284. expect(onOpenChange.getCall(0).args[0].itemKey).toEqual(2);
  285. expect(
  286. document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-item-sub .${BASE_CLASS_PREFIX}-navigation-sub-open`).length > 0
  287. ).toBeTruthy();
  288. });
  289. });