@rancher/shell 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/assets/styles/global/_button.scss +5 -1
  2. package/assets/styles/global/_columns.scss +4 -0
  3. package/assets/styles/global/_layout.scss +1 -2
  4. package/assets/styles/global/_select.scss +1 -4
  5. package/assets/styles/themes/_dark.scss +4 -4
  6. package/assets/styles/themes/_light.scss +4 -3
  7. package/assets/styles/themes/_suse.scss +1 -1
  8. package/assets/styles/vendor/vue-select.scss +4 -3
  9. package/assets/translations/en-us.yaml +669 -73
  10. package/assets/translations/zh-hans.yaml +547 -165
  11. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  12. package/cloud-credential/azure.vue +23 -0
  13. package/cloud-credential/harvester.vue +25 -62
  14. package/cloud-credential/pnap.vue +80 -0
  15. package/components/.DS_Store +0 -0
  16. package/components/AdvancedSection.vue +9 -2
  17. package/components/Alert.vue +2 -2
  18. package/components/ButtonDropdown.vue +0 -2
  19. package/components/ButtonGroup.vue +1 -0
  20. package/components/CollapsibleCard.vue +0 -1
  21. package/components/CruResource.vue +41 -4
  22. package/components/DetailTop.vue +58 -3
  23. package/components/DisableAuthProviderModal.vue +106 -0
  24. package/{rancher-components/components/Utils/DraggableZone → components}/DraggableZone.vue +0 -0
  25. package/components/ExplorerMembers.vue +253 -30
  26. package/components/ExplorerProjectsNamespaces.vue +77 -33
  27. package/components/GrowlManager.vue +3 -3
  28. package/components/IconOrSvg.vue +149 -0
  29. package/components/LogItem.vue +69 -0
  30. package/components/PodSecurityAdmission.vue +302 -0
  31. package/components/PromptModal.vue +1 -0
  32. package/components/ResourceDetail/Masthead.vue +54 -2
  33. package/components/ResourceDetail/index.vue +12 -5
  34. package/components/ResourceList/Masthead.vue +11 -1
  35. package/components/ResourceList/ResourceLoadingIndicator.vue +12 -2
  36. package/components/ResourceList/index.vue +53 -12
  37. package/components/ResourceList/resource-list.config.js +7 -0
  38. package/components/ResourceTable.vue +31 -6
  39. package/components/SimpleBox.vue +1 -1
  40. package/components/SortableTable/THead.vue +15 -5
  41. package/components/SortableTable/index.vue +21 -10
  42. package/components/Tabbed/index.vue +20 -15
  43. package/components/__tests__/.DS_Store +0 -0
  44. package/components/__tests__/AsyncButton.test.ts +140 -0
  45. package/components/__tests__/BackLink.test.ts +33 -0
  46. package/components/__tests__/ButtonGroup.test.ts +124 -0
  47. package/components/__tests__/ClusterBadge.test.ts +32 -0
  48. package/components/__tests__/CollapsibleCard.test.ts +64 -0
  49. package/components/__tests__/ConsumptionGauge.test.ts +88 -0
  50. package/components/__tests__/CruResource.test.ts +3 -2
  51. package/components/__tests__/FixedBanner.test.ts +129 -0
  52. package/components/__tests__/GrowlManager.test.ts +147 -0
  53. package/components/__tests__/NamespaceFilter.test.ts +33 -25
  54. package/components/__tests__/PercentageBar.test.ts +32 -0
  55. package/components/__tests__/PodSecurityAdmission.test.ts +398 -0
  56. package/components/auth/AuthBanner.vue +20 -10
  57. package/components/auth/RoleDetailEdit.vue +26 -17
  58. package/components/auth/SelectPrincipal.vue +36 -5
  59. package/components/form/ArrayList.vue +3 -35
  60. package/components/form/ArrayListGrouped.vue +13 -4
  61. package/components/form/ArrayListSelect.vue +5 -5
  62. package/components/form/Error.vue +8 -0
  63. package/components/form/KeyValue.vue +39 -7
  64. package/components/form/LabeledSelect.vue +5 -2
  65. package/components/form/Labels.vue +46 -16
  66. package/components/form/Members/ClusterPermissionsEditor.vue +17 -17
  67. package/components/form/Members/MembershipEditor.vue +12 -12
  68. package/components/form/NameNsDescription.vue +1 -1
  69. package/components/form/NodeScheduling.vue +1 -1
  70. package/components/form/Probe.vue +3 -3
  71. package/components/form/ResourceQuota/Project.vue +6 -6
  72. package/components/form/ResourceTabs/index.vue +1 -6
  73. package/components/form/Security.vue +7 -6
  74. package/components/form/Select.vue +3 -2
  75. package/components/form/SelectOrCreateAuthSecret.vue +22 -29
  76. package/components/form/ServicePorts.vue +8 -0
  77. package/components/form/WorkloadPorts.vue +7 -1
  78. package/components/form/__tests__/ArrayList.test.ts +74 -0
  79. package/components/form/__tests__/ArrayListGrouped.test.ts +6 -4
  80. package/components/formatter/Checked.vue +1 -1
  81. package/components/formatter/ClusterLink.vue +5 -0
  82. package/components/formatter/IconIsDefault.vue +2 -2
  83. package/components/formatter/InternalExternalIP.vue +11 -8
  84. package/components/formatter/LiveDuration.vue +78 -0
  85. package/components/formatter/WorkloadHealthScale.vue +5 -3
  86. package/components/nav/Header.vue +6 -3
  87. package/components/nav/NamespaceFilter.vue +146 -63
  88. package/components/nav/TopLevelMenu.vue +22 -19
  89. package/components/nav/WindowManager/ContainerLogs.vue +83 -126
  90. package/components/nav/WindowManager/ContainerShell.vue +9 -7
  91. package/components/nav/WindowManager/Window.vue +2 -0
  92. package/components/nav/WindowManager/index.vue +10 -0
  93. package/config/elemental-types.js +9 -0
  94. package/config/features.js +2 -0
  95. package/config/home-links.js +4 -1
  96. package/config/pod-security-admission.ts +82 -0
  97. package/config/product/apps.js +1 -1
  98. package/config/product/auth.js +6 -5
  99. package/config/product/explorer.js +6 -6
  100. package/config/product/fleet.js +1 -1
  101. package/config/product/manager.js +6 -2
  102. package/config/secret.js +0 -1
  103. package/config/settings.ts +26 -9
  104. package/config/table-headers.js +22 -11
  105. package/config/types.js +4 -1
  106. package/content/docs/zh-hans/getting-started.md +113 -137
  107. package/content/docs/zh-hans/whats-new.md +8 -46
  108. package/creators/pkg/package-lock.json +37 -0
  109. package/creators/pkg/package.json +1 -1
  110. package/detail/catalog.cattle.io.app.vue +1 -1
  111. package/detail/pod.vue +1 -1
  112. package/detail/provisioning.cattle.io.cluster.vue +35 -9
  113. package/detail/service.vue +2 -9
  114. package/detail/workload/index.vue +0 -1
  115. package/dialog/AddClusterMemberDialog.vue +22 -28
  116. package/dialog/AddProjectMemberDialog.vue +53 -9
  117. package/dialog/DiagnosticTimingsDialog.vue +8 -7
  118. package/dialog/DrainNode.vue +44 -48
  119. package/dialog/ForceMachineRemoveDialog.vue +5 -7
  120. package/dialog/GenericPrompt.vue +15 -20
  121. package/dialog/RollbackWorkloadDialog.vue +15 -46
  122. package/dialog/RotateCertificatesDialog.vue +5 -7
  123. package/dialog/RotateEncryptionKeyDialog.vue +5 -9
  124. package/dialog/SaveAsRKETemplateDialog.vue +5 -13
  125. package/dialog/ScaleMachineDownDialog.vue +1 -1
  126. package/dialog/ScalePoolDownDialog.vue +121 -0
  127. package/edit/__tests__/management.cattle.io.setting.test.ts +3 -3
  128. package/edit/auth/azuread.vue +16 -16
  129. package/edit/auth/github.vue +8 -0
  130. package/edit/auth/googleoauth.vue +10 -1
  131. package/edit/auth/ldap/index.vue +10 -0
  132. package/edit/auth/oidc.vue +10 -0
  133. package/edit/auth/saml.vue +10 -0
  134. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -1
  135. package/edit/cloudcredential.vue +3 -7
  136. package/edit/logging-flow/Match.vue +39 -8
  137. package/edit/logging-flow/index.vue +27 -4
  138. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +107 -0
  139. package/edit/management.cattle.io.project.vue +8 -1
  140. package/edit/management.cattle.io.setting.vue +5 -2
  141. package/edit/management.cattle.io.user.vue +7 -1
  142. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +23 -7
  143. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +2 -2
  144. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +14 -6
  145. package/edit/namespace.vue +18 -4
  146. package/edit/networking.k8s.io.ingress/Certificate.vue +1 -0
  147. package/edit/networking.k8s.io.ingress/IngressClass.vue +8 -6
  148. package/edit/networking.k8s.io.ingress/RulePath.vue +12 -6
  149. package/edit/networking.k8s.io.ingress/index.vue +8 -6
  150. package/edit/persistentvolume/index.vue +30 -27
  151. package/edit/persistentvolume/plugins/cephfs.vue +29 -29
  152. package/edit/persistentvolume/plugins/csi.vue +102 -62
  153. package/edit/persistentvolume/plugins/fc.vue +19 -19
  154. package/edit/persistentvolume/plugins/iscsi.vue +45 -45
  155. package/edit/persistentvolume/plugins/rbd.vue +39 -39
  156. package/edit/persistentvolumeclaim.vue +78 -75
  157. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -7
  158. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +10 -1
  159. package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +87 -27
  160. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -6
  161. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +93 -0
  162. package/edit/provisioning.cattle.io.cluster/import.vue +1 -1
  163. package/edit/provisioning.cattle.io.cluster/index.vue +29 -6
  164. package/edit/provisioning.cattle.io.cluster/rke2.vue +440 -152
  165. package/edit/secret/index.vue +3 -7
  166. package/edit/service.vue +3 -1
  167. package/edit/storage.k8s.io.storageclass/index.vue +100 -16
  168. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +114 -0
  169. package/edit/workload/__tests__/index.test.ts +98 -0
  170. package/edit/workload/index.vue +58 -8
  171. package/edit/workload/mixins/workload.js +107 -70
  172. package/edit/workload/storage/ContainerMountPaths.vue +0 -10
  173. package/edit/workload/storage/emptyDir.vue +88 -0
  174. package/edit/workload/storage/ephemeralVolume/index.vue +1 -1
  175. package/edit/workload/storage/index.vue +8 -0
  176. package/edit/workload/storage/persistentVolumeClaim/index.vue +1 -1
  177. package/layouts/default.vue +57 -44
  178. package/list/__tests__/workload.test.ts +5 -2
  179. package/list/catalog.cattle.io.app.vue +1 -0
  180. package/list/cis.cattle.io.clusterscan.vue +1 -0
  181. package/list/fleet.cattle.io.bundle.vue +5 -6
  182. package/list/fleet.cattle.io.cluster.vue +6 -3
  183. package/list/fleet.cattle.io.clusterregistrationtoken.vue +5 -6
  184. package/list/fleet.cattle.io.gitrepo.vue +4 -9
  185. package/list/helm.cattle.io.projecthelmchart.vue +1 -5
  186. package/list/logging.banzaicloud.io.clusterflow.vue +4 -1
  187. package/list/logging.banzaicloud.io.flow.vue +6 -5
  188. package/list/management.cattle.io.cluster.vue +1 -0
  189. package/list/management.cattle.io.feature.vue +3 -4
  190. package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +47 -0
  191. package/list/management.cattle.io.setting.vue +2 -2
  192. package/list/management.cattle.io.user.vue +4 -10
  193. package/list/monitoring.coreos.com.alertmanagerconfig.vue +2 -7
  194. package/list/node.vue +8 -5
  195. package/list/persistentvolume.vue +3 -3
  196. package/list/persistentvolumeclaim.vue +3 -4
  197. package/list/provisioning.cattle.io.cluster.vue +18 -19
  198. package/list/service.vue +6 -14
  199. package/list/workload.vue +43 -38
  200. package/machine-config/azure.vue +429 -60
  201. package/machine-config/pnap.vue +288 -0
  202. package/mixins/auth-config.js +1 -3
  203. package/mixins/browser-tab-visibility.js +8 -14
  204. package/mixins/chart.js +1 -1
  205. package/mixins/create-edit-view/impl.js +4 -0
  206. package/mixins/create-edit-view/index.js +4 -2
  207. package/mixins/resource-fetch-namespaced.js +98 -0
  208. package/mixins/resource-fetch.js +79 -45
  209. package/mixins/resource-manager.js +1 -23
  210. package/models/apps.controllerrevision.js +7 -0
  211. package/models/apps.daemonset.js +18 -0
  212. package/models/apps.deployment.js +44 -0
  213. package/models/apps.replicaset.js +7 -0
  214. package/models/apps.statefulset.js +18 -0
  215. package/models/batch.job.js +7 -14
  216. package/models/cluster/node.js +10 -2
  217. package/models/cluster.x-k8s.io.machine.js +26 -4
  218. package/models/cluster.x-k8s.io.machinedeployment.js +12 -2
  219. package/models/event.js +7 -0
  220. package/models/logging.banzaicloud.io.flow.js +4 -0
  221. package/models/management.cattle.io.cluster.js +1 -1
  222. package/models/management.cattle.io.clusterroletemplatebinding.js +1 -1
  223. package/models/management.cattle.io.globalrole.js +2 -2
  224. package/models/management.cattle.io.node.js +37 -2
  225. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +4 -0
  226. package/models/management.cattle.io.project.js +30 -11
  227. package/models/management.cattle.io.setting.js +1 -1
  228. package/models/management.cattle.io.user.js +37 -1
  229. package/models/namespace.js +42 -5
  230. package/models/persistentvolume.js +14 -2
  231. package/models/pod.js +15 -0
  232. package/models/projectroletemplatebinding.js +7 -0
  233. package/models/provisioning.cattle.io.cluster.js +61 -10
  234. package/models/rke-machine.cattle.io.pnapmachinetemplate.js +15 -0
  235. package/models/service.js +14 -13
  236. package/models/storage.k8s.io.storageclass.js +33 -18
  237. package/models/workload.js +38 -7
  238. package/nuxt.config.js +27 -17
  239. package/package.json +7 -7
  240. package/pages/about.vue +14 -2
  241. package/pages/c/_cluster/apps/charts/index.vue +4 -3
  242. package/pages/c/_cluster/apps/charts/install.vue +59 -22
  243. package/pages/c/_cluster/auth/config/_id.vue +6 -0
  244. package/pages/c/_cluster/auth/config/index.vue +8 -6
  245. package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
  246. package/pages/c/_cluster/auth/roles/index.vue +1 -1
  247. package/pages/c/_cluster/explorer/index.vue +12 -6
  248. package/pages/c/_cluster/longhorn/index.vue +1 -1
  249. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +15 -4
  250. package/pages/c/_cluster/monitoring/index.vue +1 -1
  251. package/pages/c/_cluster/neuvector/index.vue +1 -1
  252. package/pages/c/_cluster/settings/performance.vue +48 -2
  253. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +34 -1
  254. package/pages/c/_cluster/uiplugins/index.vue +28 -2
  255. package/pages/diagnostic.vue +5 -4
  256. package/pages/home.vue +105 -30
  257. package/pages/prefs.vue +23 -12
  258. package/pages/rio/mesh.vue +1 -1
  259. package/pkg/dynamic-importer.lib.js +8 -0
  260. package/pkg/vue.config.js +4 -0
  261. package/plugins/dashboard-store/__tests__/mutations.spec.js +406 -0
  262. package/plugins/dashboard-store/actions.js +32 -25
  263. package/plugins/dashboard-store/getters.js +50 -33
  264. package/plugins/dashboard-store/mutations.js +134 -28
  265. package/plugins/dashboard-store/resource-class.js +21 -41
  266. package/plugins/steve/actions.js +30 -0
  267. package/plugins/steve/caches/resourceCache.js +60 -0
  268. package/plugins/steve/getters.js +44 -1
  269. package/plugins/steve/mutations.js +97 -36
  270. package/plugins/steve/resourceWatcher.js +277 -0
  271. package/plugins/steve/schema.utils.js +25 -0
  272. package/plugins/steve/subscribe.js +288 -115
  273. package/plugins/steve/worker/index.js +17 -0
  274. package/plugins/steve/worker/web-worker.advanced.js +302 -0
  275. package/plugins/steve/{web-worker.steve-sub-worker.js → worker/web-worker.basic.js} +3 -44
  276. package/rancher-components/Card/Card.vue +3 -3
  277. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +1 -0
  278. package/rancher-components/StringList/StringList.test.ts +45 -420
  279. package/rancher-components/StringList/StringList.vue +1 -10
  280. package/rancher-components/components/Banner/Banner.test.ts +44 -0
  281. package/rancher-components/components/Banner/Banner.vue +129 -61
  282. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +13 -22
  283. package/rancher-components/components/Form/Checkbox/Checkbox.vue +8 -6
  284. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +9 -9
  285. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -1
  286. package/rancher-components/components/StringList/StringList.test.ts +7 -7
  287. package/rancher-components/components/StringList/StringList.vue +21 -15
  288. package/scripts/test-plugins-build.sh +8 -0
  289. package/static/loading-indicator.html +1 -1
  290. package/store/index.js +54 -3
  291. package/store/plugins.js +0 -17
  292. package/store/pnap.js +128 -0
  293. package/store/prefs.js +4 -2
  294. package/store/type-map.js +55 -13
  295. package/types/pod-security-admission.ts +36 -0
  296. package/types/shell/index.d.ts +496 -396
  297. package/utils/__tests__/object.test.ts +17 -1
  298. package/utils/__tests__/pod-security-admission.test.ts +61 -0
  299. package/utils/async.ts +36 -0
  300. package/utils/color.js +45 -0
  301. package/utils/crypto/browserHashUtils.js +18 -0
  302. package/utils/dynamic-importer.js +8 -0
  303. package/utils/install-redirect.js +1 -1
  304. package/utils/object.js +24 -0
  305. package/utils/pod-security-admission.ts +39 -0
  306. package/utils/socket.js +61 -24
  307. package/utils/string.js +2 -0
  308. package/utils/svg-filter.js +301 -0
  309. package/utils/time.js +49 -0
  310. package/utils/validators/cidr.js +4 -0
  311. package/utils/validators/formRules/__tests__/index.test.ts +23 -3
  312. package/utils/validators/formRules/index.ts +14 -0
  313. package/config/product/harvester-manager.js +0 -162
  314. package/edit/harvesterhci.io.management.cluster.vue +0 -153
  315. package/list/harvesterhci.io.management.cluster.vue +0 -241
  316. package/machine-config/harvester.vue +0 -693
  317. package/models/harvesterhci.io.management.cluster.js +0 -228
  318. package/pages/c/_cluster/harvesterManager/index.vue +0 -24
  319. package/rancher-components/Card/Card.test.ts +0 -39
  320. package/rancher-components/Utils/DraggableZone/DraggableZone.vue +0 -181
  321. package/rancher-components/Utils/DraggableZone/index.ts +0 -1
  322. package/rancher-components/components/Utils/DraggableZone/index.ts +0 -1
@@ -1,455 +1,80 @@
1
- import { mount, Wrapper } from '@vue/test-utils';
1
+ import { mount } from '@vue/test-utils';
2
2
  import { StringList } from './index';
3
3
 
4
4
  describe('StringList.vue', () => {
5
5
 
6
- let wrapper: Wrapper<Vue>;
7
-
8
- beforeEach(() => {
9
- wrapper = mount(StringList, {
6
+ it('is empty', () => {
7
+ const wrapper = mount(StringList, {
10
8
  propsData: { items: [] },
11
9
  });
12
- });
13
-
14
- describe('List box', () => {
15
-
16
- it('is empty', () => {
17
- const box = wrapper.find('[data-testid="div-string-list-box"]').element as HTMLElement;
18
-
19
- expect(box.children.length).toBe(0);
20
- });
21
-
22
- it('show multiple items', async () => {
23
- const items = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k' ];
24
- await wrapper.setProps({ items });
25
-
26
- const elements = wrapper.findAll('[data-testid^="div-item"]');
27
-
28
- expect(elements.length).toBe(10);
29
- });
30
-
31
- it('double click triggers inline edit mode', async () => {
32
- const items = [ 'test' ];
33
- await wrapper.setProps({ items });
34
-
35
- const item = wrapper.find('[data-testid="div-item-test"]');
36
- await item.trigger('dblclick');
37
-
38
- const inputField = wrapper.find('[data-testid^="item-edit"]');
39
-
40
- expect(inputField.element).toBeDefined();
41
- });
42
-
43
- it('double click on empty space triggers create mode', async () => {
44
- await wrapper.setProps({ items: [] });
45
-
46
- // double click on empty space
47
- const box = wrapper.find('[data-testid="div-string-list-box"]');
48
- await box.trigger('dblclick');
49
-
50
- const inputField = wrapper.find('[data-testid="item-create"]');
51
-
52
- expect(inputField.element).toBeDefined();
53
- });
54
-
55
- it('select item when click on it', async () => {
56
- const items = [ 'test' ];
57
- await wrapper.setProps({ items });
58
-
59
- // select item
60
- const item = wrapper.find('[data-testid^="div-item"]');
61
- await item.trigger('mousedown');
62
-
63
- expect(item.element.className).toContain('selected');
64
- });
65
-
66
- it('double click to edit item not allowed when readonly', async () => {
67
- const items = [ 'test' ];
68
- await wrapper.setProps({
69
- items,
70
- readonly: true,
71
- });
72
-
73
- const item = wrapper.find('[data-testid="div-item-test"]');
74
- await item.trigger('dblclick');
75
-
76
- const inputField = wrapper.find('[data-testid^="item-edit"]');
77
-
78
- expect(inputField.element).toBeUndefined();
79
- });
80
-
81
- it('double click on empty space to create item not allowed when readonly', async () => {
82
- await wrapper.setProps({
83
- items: [],
84
- readonly: true,
85
- });
86
-
87
- // double click on empty space
88
- const box = wrapper.find('[data-testid="div-string-list-box"]');
89
- await box.trigger('dblclick');
90
-
91
- const inputField = wrapper.find('[data-testid="item-create"]');
92
-
93
- expect(inputField.element).toBeUndefined();
94
- });
95
-
96
- it('select item not allowed when readonly', async () => {
97
- const items = [ 'test' ];
98
- await wrapper.setProps({
99
- items,
100
- readonly: true,
101
- });
102
-
103
- // select item
104
- const item = wrapper.find('[data-testid^="div-item"]');
105
- await item.trigger('mousedown');
106
-
107
- expect(item.element.className).not.toContain('selected');
108
- });
10
+ const box = wrapper.find('[data-testid="div-string-list-box"]').element as HTMLElement;
109
11
 
12
+ expect(box.children.length).toBe(0);
110
13
  });
111
14
 
112
- describe('Buttons', () => {
113
-
114
- it('are visible by default', async () => {
115
- const actionButtons = wrapper.find('[data-testid="div-action-buttons"]');
116
-
117
- expect(actionButtons.element).toBeDefined();
118
- });
119
-
120
- it('are hidden when is view-only mode', async () => {
121
- await wrapper.setProps({
122
- readonly: true,
123
- });
124
- const actionButtons = wrapper.find('[data-testid="div-action-buttons"]');
125
-
126
- expect(actionButtons.element).toBeUndefined();
127
- });
128
-
129
- describe('Add button', () => {
130
-
131
- it('is enabled by default', async () => {
132
- const addButton = wrapper.find('[data-testid="button-add"]')?.element as HTMLButtonElement;
133
-
134
- expect(addButton.disabled).toBe(false);
135
- });
136
-
137
- it('show the input field when is clicked', async () => {
138
- // click add button
139
- const addButton = wrapper.find('[data-testid="button-add"]');
140
- await addButton.trigger('click');
141
-
142
- const inputField = wrapper.find('[data-testid="item-create"]');
143
-
144
- expect(inputField.element).toBeDefined();
145
- });
146
-
147
- it('is disabled when create mode is active', async () => {
148
- // click add button
149
- const addButton = wrapper.find('[data-testid="button-add"]');
150
- await addButton.trigger('click');
151
-
152
- wrapper.find('[data-testid="item-create"]');
153
-
154
- const buttonElem = addButton.element as HTMLButtonElement;
155
-
156
- expect(buttonElem.disabled).toBe(true);
157
- });
158
-
159
- });
160
-
161
- describe('Remove button', () => {
162
-
163
- it('is disabled by default', async () => {
164
- const removeButton = wrapper.find('[data-testid="button-remove"]');
165
- const buttonElem = removeButton.element as HTMLButtonElement;
166
-
167
- expect(buttonElem.disabled).toBe(true);
168
- });
169
-
170
- it('is enabled when create mode is active', async () => {
171
- // click add button
172
- const addButton = wrapper.find('[data-testid="button-add"]');
173
- await addButton.trigger('click');
174
-
175
- const removeButton = wrapper.find('[data-testid="button-remove"]');
176
- const buttonElem = removeButton.element as HTMLButtonElement;
177
-
178
- expect(buttonElem.disabled).toBe(false);
179
- });
180
-
181
- it('is enabled when edit mode is active', async () => {
182
- const items = [ 'test' ];
183
- await wrapper.setProps({ items });
184
-
185
- // activate edit mode
186
- await wrapper.setData({ editedItem: 'test' });
187
-
188
- const removeButton = wrapper.find('[data-testid="button-remove"]');
189
- const buttonElem = removeButton.element as HTMLButtonElement;
190
-
191
- expect(buttonElem.disabled).toBe(false);
192
- });
193
-
194
- it('is enabled when an item is selected', async () => {
195
- const items = [ 'test' ];
196
- await wrapper.setProps({ items });
197
-
198
- // select item
199
- await wrapper.setData({ selected: 'test' });
200
-
201
- // click remove button
202
- const removeButton = wrapper.find('[data-testid="button-remove"]');
203
- const buttonElem = removeButton.element as HTMLButtonElement;
204
-
205
- expect(buttonElem.disabled).toBe(false);
206
- });
207
-
208
- it('removes items when an item is selected', async () => {
209
- const items = [ 'a' ];
210
- await wrapper.setProps({ items });
211
-
212
- // select item
213
- await wrapper.setData({ selected: 'a' });
214
-
215
- // click remove button
216
- const removeButton = wrapper.find('[data-testid="button-remove"]');
217
- await removeButton.trigger('mousedown');
218
-
219
- await wrapper.vm.$nextTick();
220
-
221
- const itemsCount = (wrapper.emitted('change') as any)[0][0].length;
222
-
223
- expect(itemsCount).toBe(0);
224
- });
225
-
226
- it('deactivates create mode', async () => {
227
- // activate create mode
228
- await wrapper.setData({ isCreateItem: true });
229
-
230
- // click remove button
231
- const removeButton = wrapper.find('[data-testid="button-remove"]');
232
- await removeButton.trigger('mousedown');
233
-
234
- const inputField = await wrapper.find('[data-testid="item-create"]');
235
-
236
- expect(inputField.element).toBeUndefined();
237
- });
238
-
239
- it('deactivates edit mode', async () => {
240
- const items = [ 'test' ];
241
- await wrapper.setProps({ items });
242
-
243
- // activate edit mode
244
- await wrapper.setData({ editedItem: 'test' });
245
-
246
- // click remove button
247
- const removeButton = wrapper.find('[data-testid="button-remove"]');
248
- await removeButton.trigger('mousedown');
249
-
250
- const inputField = wrapper.find('[data-testid^="item-edit"]');
251
-
252
- expect(inputField.element).toBeUndefined();
253
- });
254
-
15
+ it('is showing one element', () => {
16
+ const wrapper = mount(StringList, {
17
+ propsData: { items: ['test'] },
255
18
  });
19
+ const box = wrapper.find('.string-list-box').element as HTMLElement;
256
20
 
21
+ expect(box.children.length).toBe(1);
257
22
  });
258
23
 
259
- describe('List edit', () => {
260
-
261
- const validItem = ' item name ';
262
- const emptyItem = ' ';
263
-
264
- it('save a new item in create mode by pressing Enter key', async () => {
265
- // activate create mode
266
- await wrapper.setData({ isCreateItem: true });
267
-
268
- // type item name
269
- const inputField = wrapper.find('[data-testid="item-create"]');
270
- await inputField.setValue(validItem);
271
-
272
- // press enter
273
- await inputField.trigger('keydown.enter');
274
- await wrapper.vm.$nextTick();
275
-
276
- const emitted = (wrapper.emitted('change') as any)[0][0][0];
277
-
278
- expect(emitted).toBe(validItem.trim());
279
- });
280
-
281
- it('save item in edit mode by pressing Enter key', async () => {
282
- const items = [ 'test' ];
283
- await wrapper.setProps({ items });
284
-
285
- // activate edit mode
286
- await wrapper.setData({ editedItem: 'test' });
287
- const inputField = wrapper.find('[data-testid^="item-edit"]');
288
-
289
- // edit item name
290
- await inputField.setValue(validItem);
291
-
292
- // press enter
293
- await inputField.trigger('keydown.enter');
294
- await wrapper.vm.$nextTick();
295
-
296
- const emitted = (wrapper.emitted('change') as any)[0][0][0];
297
-
298
- expect(emitted).toBe(validItem.trim());
299
- });
300
-
301
- it('reject a new item in create mode when item name is empty', async () => {
302
- // activate create mode
303
- await wrapper.setData({ isCreateItem: true });
304
-
305
- // type item name
306
- const inputField = wrapper.find('[data-testid="item-create"]');
307
- await inputField.setValue(emptyItem);
308
-
309
- // press enter
310
- await inputField.trigger('keydown.enter');
311
- await wrapper.vm.$nextTick();
312
-
313
- expect(wrapper.emitted('change')).toBeFalsy();
314
- });
315
-
316
- it('reject a new item in create mode when item name is duplicate', async () => {
317
- const items = [ 'test' ];
318
- await wrapper.setProps({ items });
319
-
320
- // activate create mode
321
- await wrapper.setData({ isCreateItem: true });
322
-
323
- // type item name
324
- const inputField = wrapper.find('[data-testid="item-create"]');
325
- await inputField.setValue('test');
326
-
327
- // press enter
328
- await inputField.trigger('keydown.enter');
329
- await wrapper.vm.$nextTick();
330
-
331
- expect(wrapper.emitted('change')).toBeFalsy();
24
+ it('action-buttons are visible', () => {
25
+ const wrapper = mount(StringList, {
26
+ propsData: { items: ['test'] },
332
27
  });
28
+ const actionButtons = wrapper.find('[data-testid="div-action-buttons"]').element as HTMLElement;
333
29
 
334
- it('reject an item in edit mode when item name is empty', async () => {
335
- const items = [ 'test' ];
336
- await wrapper.setProps({ items });
337
-
338
- // activate edit mode
339
- await wrapper.setData({ editedItem: 'test' });
340
- const inputField = wrapper.find('[data-testid^="item-edit"]');
341
-
342
- // edit item name
343
- await inputField.setValue(emptyItem);
344
-
345
- // press enter
346
- await inputField.trigger('keydown.enter');
347
- await wrapper.vm.$nextTick();
348
-
349
- expect(wrapper.emitted('change')).toBeFalsy();
350
- });
351
-
352
- it('reject an item in edit mode when item name is duplicate', async () => {
353
- const items = [ 'test', 'test-1' ];
354
- await wrapper.setProps({ items });
355
-
356
- // activate edit mode
357
- await wrapper.setData({ editedItem: 'test' });
358
- const inputField = wrapper.find('[data-testid^="item-edit"]');
359
-
360
- // edit item name
361
- await inputField.setValue('test-1');
362
-
363
- // press enter
364
- await inputField.trigger('keydown.enter');
365
- await wrapper.vm.$nextTick();
30
+ expect(actionButtons).not.toBe(undefined);
31
+ });
366
32
 
367
- expect(wrapper.emitted('change')).toBeFalsy();
33
+ it('action-buttons are hidden when is view-only mode', () => {
34
+ const wrapper = mount(StringList, {
35
+ propsData: {
36
+ items: ['test'],
37
+ readonly: true,
38
+ },
368
39
  });
40
+ const actionButtons = wrapper.find('[data-testid="div-action-buttons"]').element as HTMLElement;
369
41
 
42
+ expect(actionButtons).toBe(undefined);
370
43
  });
371
44
 
372
- describe('Errors handling', () => {
45
+ it('show new item when "items" property change', async () => {
46
+ const items = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'];
373
47
 
374
- it('show duplicate warning icon when errorMessages is defined', async () => {
375
- const items = [ 'test' ];
376
- await wrapper.setProps({
48
+ const wrapper = mount(StringList, {
49
+ propsData: {
377
50
  items,
378
- errorMessages: { duplicate: 'error, item is duplicate.' },
379
- });
380
-
381
- // activate edit mode
382
- await wrapper.setData({ isCreateItem: true });
383
-
384
- // type item name
385
- const inputField = wrapper.find('[data-testid="item-create"]');
386
- await inputField.setValue('test');
387
-
388
- const icon = wrapper.find('[data-testid="i-warning-icon"]');
389
-
390
- expect(icon.element).toBeDefined();
51
+ },
391
52
  });
53
+ const elements = wrapper.findAll('[data-testid^="div-item"]');
392
54
 
393
- it('show duplicate warning message when errorMessages is defined', async () => {
394
- const items = [ 'test' ];
395
- await wrapper.setProps({
396
- items,
397
- errorMessages: { duplicate: 'error, item is duplicate.' },
398
- });
55
+ expect(elements.length).toBe(10);
399
56
 
400
- // activate edit mode
401
- await wrapper.setData({ isCreateItem: true });
57
+ await wrapper.setProps({ items: [ ...items, 'new' ] });
402
58
 
403
- // type item name
404
- const inputField = wrapper.find('[data-testid="item-create"]');
405
- await inputField.setValue('test');
59
+ const newElements = wrapper.findAll('[data-testid^="div-item"]');
60
+ expect(newElements.length).toBe(11);
61
+ });
406
62
 
407
- const message = wrapper.find('[data-testid^="span-error-message"]');
408
-
409
- expect(message.element).toBeDefined();
410
- });
63
+ it('remove item when "items" property change', async () => {
64
+ const items = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'];
411
65
 
412
- it('emit duplicate errors', async () => {
413
- const items = [ 'test' ];
414
- await wrapper.setProps({
66
+ const wrapper = mount(StringList, {
67
+ propsData: {
415
68
  items,
416
- });
417
-
418
- // activate edit mode
419
- await wrapper.setData({ isCreateItem: true });
420
-
421
- // type item name
422
- const inputField = wrapper.find('[data-testid="item-create"]');
423
- await inputField.setValue('test');
424
-
425
- const isDuplicate = (wrapper.emitted('errors') as any)[0][0].duplicate;
426
-
427
- expect(isDuplicate).toBe(true);
69
+ },
428
70
  });
71
+ const elements = wrapper.findAll('[data-testid^="div-item"]');
72
+ expect(elements.length).toBe(10);
429
73
 
430
- it('emit duplicate errors, reset error', async () => {
431
- const items = [ 'test' ];
432
- await wrapper.setProps({
433
- items,
434
- });
435
-
436
- // activate edit mode
437
- await wrapper.setData({ isCreateItem: true });
438
-
439
- // type item name
440
- const inputField = wrapper.find('[data-testid="item-create"]');
441
-
442
- // emit duplicate errors
443
- await inputField.setValue('test');
444
-
445
- // it is not duplicate, reset duplicate error -> emit false
446
- await inputField.setValue('test-1');
447
-
448
- const isDuplicate = (wrapper.emitted('errors') as any)[0][0].duplicate;
449
-
450
- expect(isDuplicate).toBe(false);
451
- });
74
+ await wrapper.setProps({ items: [ ...items.filter(f => f !== 'a') ] });
452
75
 
76
+ const newElements = wrapper.findAll('[data-testid^="div-item"]');
77
+ expect(newElements.length).toBe(9);
453
78
  });
454
79
 
455
80
  });
@@ -410,7 +410,6 @@ export default Vue.extend({
410
410
  <LabeledInput
411
411
  v-if="editedItem && editedItem === item"
412
412
  ref="item-edit"
413
- :data-testid="`item-edit-${item}`"
414
413
  class="edit-input static"
415
414
  :value="value != null ? value : item"
416
415
  @input="onChange($event)"
@@ -424,7 +423,6 @@ export default Vue.extend({
424
423
  >
425
424
  <LabeledInput
426
425
  ref="item-create"
427
- data-testid="item-create"
428
426
  class="create-input static"
429
427
  type="text"
430
428
  :value="value"
@@ -445,7 +443,6 @@ export default Vue.extend({
445
443
  class="action-buttons"
446
444
  >
447
445
  <button
448
- data-testid="button-remove"
449
446
  class="btn btn-sm role-tertiary remove-button"
450
447
  :disabled="!selected && !isCreateItem && !editedItem"
451
448
  @mousedown.prevent="onClickMinusButton"
@@ -453,7 +450,6 @@ export default Vue.extend({
453
450
  <span class="icon icon-minus icon-sm" />
454
451
  </button>
455
452
  <button
456
- data-testid="button-add"
457
453
  class="btn btn-sm role-tertiary add-button"
458
454
  :disabled="isCreateItem || editedItem"
459
455
  @click.prevent="onClickPlusButton"
@@ -462,15 +458,10 @@ export default Vue.extend({
462
458
  </button>
463
459
  </div>
464
460
  <div class="messages">
465
- <i
466
- v-if="errorMessagesArray.length > 0"
467
- data-testid="i-warning-icon"
468
- class="icon icon-warning icon-lg"
469
- />
461
+ <i v-if="errorMessagesArray.length > 0" class="icon icon-warning icon-lg" />
470
462
  <span
471
463
  v-for="(msg, idx) in errorMessagesArray"
472
464
  :key="idx"
473
- :data-testid="`span-error-message-${msg}`"
474
465
  class="error"
475
466
  >
476
467
  {{ idx > 0 ? '; ' : '' }}
@@ -10,4 +10,48 @@ describe('component: Banner', () => {
10
10
 
11
11
  expect(element.textContent).toBe(label);
12
12
  });
13
+
14
+ it('should display an icon', () => {
15
+ const icon = 'my-icon';
16
+ const wrapper = mount(Banner, { propsData: { icon } });
17
+
18
+ const element = wrapper.find(`.${ icon }`).element;
19
+
20
+ expect(element.classList).toContain(icon);
21
+ });
22
+
23
+ it('should not display an icon', () => {
24
+ const wrapper = mount(Banner);
25
+
26
+ const element = wrapper.find(`[data-testid="banner-icon"]`).element;
27
+
28
+ expect(element).not.toBeDefined();
29
+ });
30
+
31
+ it('should emit close event', () => {
32
+ const wrapper = mount(Banner, { propsData: { closable: true } });
33
+ const element = wrapper.find(`[data-testid="banner-close"]`).element;
34
+
35
+ element.click();
36
+
37
+ expect(wrapper.emitted('close')).toHaveLength(1);
38
+ });
39
+
40
+ it('should add the right color', () => {
41
+ const color = 'red';
42
+ const wrapper = mount(Banner, { propsData: { color } });
43
+
44
+ const element = wrapper.element;
45
+
46
+ expect(element.classList).toContain(color);
47
+ });
48
+
49
+ it('should stack the banner messages', () => {
50
+ const stacked = true;
51
+ const wrapper = mount(Banner, { propsData: { stacked } });
52
+
53
+ const element = wrapper.find(`[data-testid="banner-content"]`).element;
54
+
55
+ expect(element.classList).toContain('stacked');
56
+ });
13
57
  });