@api-client/ui 0.0.11 → 0.0.13

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 (242) hide show
  1. package/.eslintrc +8 -0
  2. package/demo/elements/authorization/cc.ts +56 -27
  3. package/demo/elements/index.html +3 -0
  4. package/demo/elements/store/file-picker.html +15 -0
  5. package/demo/elements/store/file-picker.ts +134 -0
  6. package/demo/elements/store/index.html +19 -0
  7. package/demo/store/StorePlugin.js +1 -0
  8. package/dist/bindings/base/FileBindings.d.ts +4 -0
  9. package/dist/bindings/base/FileBindings.d.ts.map +1 -1
  10. package/dist/bindings/base/FileBindings.js +21 -1
  11. package/dist/bindings/base/FileBindings.js.map +1 -1
  12. package/dist/bindings/base/StoreBindings.d.ts +6 -17
  13. package/dist/bindings/base/StoreBindings.d.ts.map +1 -1
  14. package/dist/bindings/base/StoreBindings.js +15 -60
  15. package/dist/bindings/base/StoreBindings.js.map +1 -1
  16. package/dist/bindings/web/WebFileBindings.js +1 -1
  17. package/dist/bindings/web/WebFileBindings.js.map +1 -1
  18. package/dist/define/http/certificate-add.d.ts +9 -0
  19. package/dist/define/http/certificate-add.d.ts.map +1 -0
  20. package/dist/define/http/certificate-add.js +10 -0
  21. package/dist/define/http/certificate-add.js.map +1 -0
  22. package/dist/define/store/file-picker.d.ts +9 -0
  23. package/dist/define/store/file-picker.d.ts.map +1 -0
  24. package/dist/define/store/file-picker.js +10 -0
  25. package/dist/define/store/file-picker.js.map +1 -0
  26. package/dist/define/{files → store}/share-file.d.ts +1 -1
  27. package/dist/define/store/share-file.d.ts.map +1 -0
  28. package/dist/define/{files → store}/share-file.js +2 -2
  29. package/dist/define/store/share-file.js.map +1 -0
  30. package/dist/define/ui/ui-segmented-button-set.d.ts +1 -1
  31. package/dist/define/ui/ui-segmented-button-set.d.ts.map +1 -1
  32. package/dist/define/ui/ui-segmented-button-set.js.map +1 -1
  33. package/dist/elements/authorization/ui/CC.styles.d.ts.map +1 -1
  34. package/dist/elements/authorization/ui/CC.styles.js +4 -9
  35. package/dist/elements/authorization/ui/CC.styles.js.map +1 -1
  36. package/dist/elements/authorization/ui/CcAuthorization.d.ts +14 -29
  37. package/dist/elements/authorization/ui/CcAuthorization.d.ts.map +1 -1
  38. package/dist/elements/authorization/ui/CcAuthorization.js +67 -158
  39. package/dist/elements/authorization/ui/CcAuthorization.js.map +1 -1
  40. package/dist/elements/http/CertificateAdd.element.d.ts +91 -0
  41. package/dist/elements/http/CertificateAdd.element.d.ts.map +1 -0
  42. package/dist/elements/http/CertificateAdd.element.js +389 -0
  43. package/dist/elements/http/CertificateAdd.element.js.map +1 -0
  44. package/dist/elements/http/CertificateAdd.styles.d.ts +3 -0
  45. package/dist/elements/http/CertificateAdd.styles.d.ts.map +1 -0
  46. package/dist/elements/http/CertificateAdd.styles.js +61 -0
  47. package/dist/elements/http/CertificateAdd.styles.js.map +1 -0
  48. package/dist/elements/project/ProjectRunReport.d.ts +2 -1
  49. package/dist/elements/project/ProjectRunReport.d.ts.map +1 -1
  50. package/dist/elements/project/ProjectRunReport.js.map +1 -1
  51. package/dist/elements/store/FilePicker.element.d.ts +87 -0
  52. package/dist/elements/store/FilePicker.element.d.ts.map +1 -0
  53. package/dist/elements/store/FilePicker.element.js +263 -0
  54. package/dist/elements/store/FilePicker.element.js.map +1 -0
  55. package/dist/elements/store/FilePicker.styles.d.ts +3 -0
  56. package/dist/elements/store/FilePicker.styles.d.ts.map +1 -0
  57. package/dist/elements/store/FilePicker.styles.js +73 -0
  58. package/dist/elements/store/FilePicker.styles.js.map +1 -0
  59. package/dist/elements/store/FilesLib.d.ts +10 -0
  60. package/dist/elements/store/FilesLib.d.ts.map +1 -0
  61. package/dist/elements/store/FilesLib.js +38 -0
  62. package/dist/elements/store/FilesLib.js.map +1 -0
  63. package/dist/elements/{files/ShareFile.d.ts → store/ShareFile.element.d.ts} +1 -1
  64. package/dist/elements/store/ShareFile.element.d.ts.map +1 -0
  65. package/dist/elements/{files/ShareFile.js → store/ShareFile.element.js} +1 -1
  66. package/dist/elements/store/ShareFile.element.js.map +1 -0
  67. package/dist/elements/store/ShareFile.styles.d.ts.map +1 -0
  68. package/dist/elements/{files → store}/ShareFile.styles.js.map +1 -1
  69. package/dist/events/EventTypes.d.ts +7 -7
  70. package/dist/events/EventTypes.d.ts.map +1 -1
  71. package/dist/events/EventTypes.js +8 -7
  72. package/dist/events/EventTypes.js.map +1 -1
  73. package/dist/events/Events.d.ts +7 -1
  74. package/dist/events/Events.d.ts.map +1 -1
  75. package/dist/events/Events.js +2 -0
  76. package/dist/events/Events.js.map +1 -1
  77. package/dist/events/FilesystemEvents.d.ts +8 -0
  78. package/dist/events/FilesystemEvents.d.ts.map +1 -0
  79. package/dist/events/FilesystemEvents.js +59 -0
  80. package/dist/events/FilesystemEvents.js.map +1 -0
  81. package/dist/events/HttpClientEvents.d.ts +0 -2
  82. package/dist/events/HttpClientEvents.d.ts.map +1 -1
  83. package/dist/events/HttpClientEvents.js +0 -2
  84. package/dist/events/HttpClientEvents.js.map +1 -1
  85. package/dist/events/StoreEvents.d.ts +8 -1
  86. package/dist/events/StoreEvents.d.ts.map +1 -1
  87. package/dist/events/StoreEvents.js +19 -0
  88. package/dist/events/StoreEvents.js.map +1 -1
  89. package/dist/http-client/idb/Arc18DataUpgrade.d.ts +0 -8
  90. package/dist/http-client/idb/Arc18DataUpgrade.d.ts.map +1 -1
  91. package/dist/http-client/idb/Arc18DataUpgrade.js +11 -206
  92. package/dist/http-client/idb/Arc18DataUpgrade.js.map +1 -1
  93. package/dist/http-client/store/StoreBroadcast.d.ts +0 -5
  94. package/dist/http-client/store/StoreBroadcast.d.ts.map +1 -1
  95. package/dist/http-client/store/StoreBroadcast.js +0 -7
  96. package/dist/http-client/store/StoreBroadcast.js.map +1 -1
  97. package/dist/lib/files/FileUtils.d.ts +9 -0
  98. package/dist/lib/files/FileUtils.d.ts.map +1 -0
  99. package/dist/lib/files/FileUtils.js +13 -0
  100. package/dist/lib/files/FileUtils.js.map +1 -0
  101. package/dist/mixins/RouteMixin.d.ts +4 -0
  102. package/dist/mixins/RouteMixin.d.ts.map +1 -1
  103. package/dist/mixins/RouteMixin.js +1 -0
  104. package/dist/mixins/RouteMixin.js.map +1 -1
  105. package/dist/pages/ApplicationScreen.d.ts +1 -1
  106. package/dist/pages/ApplicationScreen.d.ts.map +1 -1
  107. package/dist/pages/ApplicationScreen.js +4 -2
  108. package/dist/pages/ApplicationScreen.js.map +1 -1
  109. package/dist/pages/api-client/ApiClient.screen.d.ts +4 -6
  110. package/dist/pages/api-client/ApiClient.screen.d.ts.map +1 -1
  111. package/dist/pages/api-client/ApiClient.screen.js +39 -31
  112. package/dist/pages/api-client/ApiClient.screen.js.map +1 -1
  113. package/dist/pages/api-client/ApiClient.styles.d.ts.map +1 -1
  114. package/dist/pages/api-client/ApiClient.styles.js +0 -12
  115. package/dist/pages/api-client/ApiClient.styles.js.map +1 -1
  116. package/dist/pages/api-client/Authenticate.screen.d.ts +1 -1
  117. package/dist/pages/api-client/Authenticate.screen.d.ts.map +1 -1
  118. package/dist/pages/api-client/Authenticate.screen.js +2 -2
  119. package/dist/pages/api-client/Authenticate.screen.js.map +1 -1
  120. package/dist/pages/api-client/pages/Files.page.d.ts +6 -35
  121. package/dist/pages/api-client/pages/Files.page.d.ts.map +1 -1
  122. package/dist/pages/api-client/pages/Files.page.js +45 -141
  123. package/dist/pages/api-client/pages/Files.page.js.map +1 -1
  124. package/dist/pages/api-client/pages/Shared.page.d.ts +1 -5
  125. package/dist/pages/api-client/pages/Shared.page.d.ts.map +1 -1
  126. package/dist/pages/api-client/pages/Shared.page.js +1 -40
  127. package/dist/pages/api-client/pages/Shared.page.js.map +1 -1
  128. package/dist/pages/demo/DemoPage.d.ts +7 -0
  129. package/dist/pages/demo/DemoPage.d.ts.map +1 -1
  130. package/dist/pages/demo/DemoPage.js +14 -0
  131. package/dist/pages/demo/DemoPage.js.map +1 -1
  132. package/dist/store/FileSystem.d.ts +90 -0
  133. package/dist/store/FileSystem.d.ts.map +1 -0
  134. package/dist/store/FileSystem.js +260 -0
  135. package/dist/store/FileSystem.js.map +1 -0
  136. package/dist/styles/global-styles.d.ts.map +1 -1
  137. package/dist/styles/global-styles.js +7 -0
  138. package/dist/styles/global-styles.js.map +1 -1
  139. package/dist/ui/button/SegmentedButtonsSet.d.ts +14 -0
  140. package/dist/ui/button/SegmentedButtonsSet.d.ts.map +1 -1
  141. package/dist/ui/button/SegmentedButtonsSet.js.map +1 -1
  142. package/dist/ui/icons/Icons.d.ts +2 -1
  143. package/dist/ui/icons/Icons.d.ts.map +1 -1
  144. package/dist/ui/icons/Icons.js +1 -0
  145. package/dist/ui/icons/Icons.js.map +1 -1
  146. package/dist/ui/list/UiDropdownList.d.ts +9 -1
  147. package/dist/ui/list/UiDropdownList.d.ts.map +1 -1
  148. package/dist/ui/list/UiDropdownList.js +39 -17
  149. package/dist/ui/list/UiDropdownList.js.map +1 -1
  150. package/dist/ui/list/UiList.d.ts +6 -1
  151. package/dist/ui/list/UiList.d.ts.map +1 -1
  152. package/dist/ui/list/UiList.js +24 -9
  153. package/dist/ui/list/UiList.js.map +1 -1
  154. package/dist/ui/notification/SnackNotifications.d.ts +1 -0
  155. package/dist/ui/notification/SnackNotifications.d.ts.map +1 -1
  156. package/dist/ui/notification/SnackNotifications.js +7 -0
  157. package/dist/ui/notification/SnackNotifications.js.map +1 -1
  158. package/dist/ui/table/DataTable.d.ts +4 -0
  159. package/dist/ui/table/DataTable.d.ts.map +1 -1
  160. package/dist/ui/table/DataTable.js +23 -1
  161. package/dist/ui/table/DataTable.js.map +1 -1
  162. package/package.json +1 -1
  163. package/src/bindings/base/FileBindings.ts +25 -1
  164. package/src/bindings/base/StoreBindings.ts +16 -73
  165. package/src/bindings/web/WebFileBindings.ts +1 -1
  166. package/src/define/http/certificate-add.ts +12 -0
  167. package/src/define/store/file-picker.ts +12 -0
  168. package/src/define/{files → store}/share-file.ts +2 -2
  169. package/src/define/ui/ui-segmented-button-set.ts +1 -1
  170. package/src/elements/authorization/ui/CC.styles.ts +4 -9
  171. package/src/elements/authorization/ui/CcAuthorization.ts +67 -167
  172. package/src/elements/http/CertificateAdd.element.ts +443 -0
  173. package/src/elements/http/CertificateAdd.styles.ts +61 -0
  174. package/src/elements/project/ProjectRunReport.ts +2 -1
  175. package/src/elements/store/FilePicker.element.ts +297 -0
  176. package/src/elements/store/FilePicker.styles.ts +73 -0
  177. package/src/elements/store/FilesLib.ts +32 -0
  178. package/src/events/EventTypes.ts +8 -7
  179. package/src/events/Events.ts +2 -0
  180. package/src/events/FilesystemEvents.ts +63 -0
  181. package/src/events/HttpClientEvents.ts +0 -2
  182. package/src/events/StoreEvents.ts +21 -1
  183. package/src/http-client/idb/Arc18DataUpgrade.ts +84 -84
  184. package/src/http-client/store/StoreBroadcast.ts +0 -8
  185. package/src/lib/files/FileUtils.ts +12 -0
  186. package/src/mixins/RouteMixin.ts +8 -1
  187. package/src/pages/ApplicationScreen.ts +5 -3
  188. package/src/pages/api-client/ApiClient.screen.ts +42 -33
  189. package/src/pages/api-client/ApiClient.styles.ts +0 -12
  190. package/src/pages/api-client/Authenticate.screen.ts +2 -2
  191. package/src/pages/api-client/pages/Files.page.ts +48 -164
  192. package/src/pages/api-client/pages/Shared.page.ts +2 -40
  193. package/src/pages/demo/DemoPage.ts +17 -0
  194. package/src/store/FileSystem.ts +325 -0
  195. package/src/styles/global-styles.ts +7 -0
  196. package/src/ui/button/SegmentedButtonsSet.ts +16 -1
  197. package/src/ui/icons/Icons.ts +2 -1
  198. package/src/ui/list/UiDropdownList.ts +44 -17
  199. package/src/ui/list/UiList.ts +26 -10
  200. package/src/ui/notification/SnackNotifications.ts +8 -0
  201. package/src/ui/table/DataTable.ts +29 -3
  202. package/test/elements/http/BodyFormdataEditorElement.test.ts +458 -454
  203. package/test/elements/http/BodyMultipartEditorElement.test.ts +609 -605
  204. package/test/elements/http/BodyRawEditorElement.test.ts +60 -56
  205. package/test/elements/http/CertificateAdd.test.ts +430 -0
  206. package/test/elements/store/FilePicker.test.ts +241 -0
  207. package/test/env.js +3 -0
  208. package/test/events/EventTypes.test.ts +0 -22
  209. package/test/helpers/StoreHelper.ts +390 -0
  210. package/test/helpers/UiMock.ts +19 -2
  211. package/tsconfig.eslint.json +3 -1
  212. package/web-test-runner.config.mjs +50 -3
  213. package/dist/define/files/share-file.d.ts.map +0 -1
  214. package/dist/define/files/share-file.js.map +0 -1
  215. package/dist/elements/files/ShareFile.d.ts.map +0 -1
  216. package/dist/elements/files/ShareFile.js.map +0 -1
  217. package/dist/elements/files/ShareFile.styles.d.ts.map +0 -1
  218. package/dist/events/http-client/models/CertificatesEvents.d.ts +0 -12
  219. package/dist/events/http-client/models/CertificatesEvents.d.ts.map +0 -1
  220. package/dist/events/http-client/models/CertificatesEvents.js +0 -18
  221. package/dist/events/http-client/models/CertificatesEvents.js.map +0 -1
  222. package/dist/http-client/idb/AuthDataModel.d.ts +0 -60
  223. package/dist/http-client/idb/AuthDataModel.d.ts.map +0 -1
  224. package/dist/http-client/idb/AuthDataModel.js +0 -150
  225. package/dist/http-client/idb/AuthDataModel.js.map +0 -1
  226. package/dist/http-client/idb/HostsModel.d.ts +0 -25
  227. package/dist/http-client/idb/HostsModel.d.ts.map +0 -1
  228. package/dist/http-client/idb/HostsModel.js +0 -82
  229. package/dist/http-client/idb/HostsModel.js.map +0 -1
  230. package/dist/http-client/idb/LegacyMockedStore.d.ts +0 -214
  231. package/dist/http-client/idb/LegacyMockedStore.d.ts.map +0 -1
  232. package/dist/http-client/idb/LegacyMockedStore.js +0 -486
  233. package/dist/http-client/idb/LegacyMockedStore.js.map +0 -1
  234. package/src/events/http-client/models/CertificatesEvents.ts +0 -23
  235. package/src/http-client/idb/AuthDataModel.ts +0 -175
  236. package/src/http-client/idb/HostsModel.ts +0 -125
  237. package/src/http-client/idb/LegacyMockedStore.ts +0 -544
  238. package/test/apic-ui.test.ts +0 -31
  239. /package/dist/elements/{files → store}/ShareFile.styles.d.ts +0 -0
  240. /package/dist/elements/{files → store}/ShareFile.styles.js +0 -0
  241. /package/src/elements/{files/ShareFile.ts → store/ShareFile.element.ts} +0 -0
  242. /package/src/elements/{files → store}/ShareFile.styles.ts +0 -0
@@ -7,460 +7,464 @@ import SwitchElement from '../../../src/ui/input/SwitchElement.js';
7
7
  import { UiButtonElement } from '../../../src/define/ui/ui-button.js';
8
8
  import '../../../src/define/http/http-body-urlencoded-editor.js';
9
9
 
10
- describe('BodyUrlEncodedEditor', () => {
11
- async function basicFixture(): Promise<BodyFormdataEditorElement> {
12
- return fixture(html`<http-body-urlencoded-editor allowFormInfo></http-body-urlencoded-editor>`);
13
- }
14
-
15
- async function valueFixture(value: string): Promise<BodyFormdataEditorElement> {
16
- return fixture(html`<http-body-urlencoded-editor .value="${value}" allowFormInfo></http-body-urlencoded-editor>`);
17
- }
18
-
19
- async function autoEncodeFixture(): Promise<BodyFormdataEditorElement> {
20
- return fixture(html`<http-body-urlencoded-editor autoEncode allowFormInfo></http-body-urlencoded-editor>`);
21
- }
22
-
23
- const generator = new ProjectMock();
24
-
25
- before(async () => loadMonaco());
26
-
27
- describe('Empty state', () => {
28
- let element: BodyFormdataEditorElement;
29
- beforeEach(async () => { element = await basicFixture(); })
30
-
31
- it('renders empty message', () => {
32
- const node = element.shadowRoot!.querySelector('.empty-message');
33
- assert.ok(node);
34
- });
35
-
36
- it('renders the form mime information', () => {
37
- const node = element.shadowRoot!.querySelector('.form-info');
38
- assert.ok(node);
39
- });
40
-
41
- it('has empty model', () => {
42
- assert.deepEqual(element.model, []);
43
- });
44
- });
45
-
46
- describe('adding a property', () => {
47
- let element: BodyFormdataEditorElement;
48
- beforeEach(async () => { element = await basicFixture(); })
49
-
50
- it('adds a model item on add button click', () => {
51
- element.addParameter();
52
- assert.lengthOf(element.model, 1);
53
- });
54
-
55
- it('does not add a model when readonly', () => {
56
- element.readOnly = true;
57
- element.addParameter();
58
- assert.lengthOf(element.model, 0);
59
- });
60
-
61
- it('does not add a model when disabled', () => {
62
- element.disabled = true;
63
- element.addParameter();
64
- assert.lengthOf(element.model, 0);
65
- });
66
-
67
- it('model item has basic schema', () => {
68
- element.addParameter();
69
- const p = Property.String();
70
- assert.deepEqual(element.model[0], p.toJSON());
71
- });
72
-
73
- it('adds an item with undefined model', () => {
74
- // @ts-ignore
75
- element.model = undefined;
76
- element.addParameter();
77
- assert.lengthOf(element.model, 1);
78
- });
79
-
80
- it('focuses on the added item', async () => {
81
- const spy = sinon.spy(element, 'focusLast');
82
- element.addParameter();
83
- await aTimeout(0);
84
- assert.isTrue(spy.called);
85
- });
86
-
87
- it('does not notify model change', async () => {
88
- // there's no point of storing the model without empty values. They are not generating
89
- // any editor value
90
- const spy = sinon.spy();
91
- element.addEventListener('change', spy);
92
- element.addParameter();
93
- assert.isFalse(spy.called);
94
- });
95
- });
96
-
97
- describe('#value', () => {
98
- let element: BodyFormdataEditorElement;
99
- beforeEach(async () => { element = await basicFixture(); })
100
-
101
- it('reads set value', () => {
102
- element.value = 'a=b';
103
- assert.equal(element.value, 'a=b');
104
- });
105
-
106
- it('generates a view model', () => {
107
- element.value = 'a=b&c=d';
108
- assert.lengthOf(element.model, 2);
109
- });
110
-
111
- it('generated model has basic properties', () => {
112
- element.value = 'a=b&c=d';
113
- const [item] = element.model;
114
- const p = Property.String('a', 'b');
115
- assert.deepEqual(item, p.toJSON());
116
- });
117
-
118
- it('clears the model when no value', () => {
119
- element.value = 'a=b&c=d';
120
- assert.lengthOf(element.model, 2);
121
- element.value = '';
122
- assert.lengthOf(element.model, 0);
123
- });
124
-
125
- it('updates existing model', () => {
126
- const p = Property.String('test', 'true');
127
- element.model = [p.toJSON()];
128
- element.value = 'a=b&c=d';
129
- assert.equal(element.model[0].name, 'a');
130
- });
131
-
132
- it('does not notify model change', async () => {
133
- // value/model setters should not dispatch change events
134
- const spy = sinon.spy();
135
- element.addEventListener('change', spy);
136
- element.value = 'a=b&c=d';
137
- assert.isFalse(spy.called);
138
- });
139
- });
140
-
141
- describe('#model', () => {
142
- let element: BodyFormdataEditorElement;
143
- beforeEach(async () => { element = await basicFixture(); })
144
-
145
- it('reads set value', () => {
146
- const p = Property.String('test', 'true');
147
- element.model = [p.toJSON()];
148
- assert.deepEqual(element.model, [p.toJSON()]);
149
- });
150
-
151
- it('generates a value', () => {
152
- const p = Property.String('test', 'true');
153
- element.model = [p.toJSON()];
154
- assert.equal(element.value, 'test=true');
155
- });
156
-
157
- it('clears the previously set value', () => {
158
- element.value = 'a=b&c=d';
159
- // @ts-ignore
160
- element.model = undefined;
161
- assert.equal(element.value, '');
162
- });
163
-
164
- it('updates existing value', () => {
165
- element.value = 'a=b&c=d';
166
- const p = Property.String('test', 'true');
167
- element.model = [p.toJSON()];
168
- assert.equal(element.value, 'test=true');
169
- });
170
-
171
- it('does not notify model change', () => {
172
- // value/model setters should not dispatch change events
173
- const spy = sinon.spy();
174
- element.addEventListener('change', spy);
175
- const p = Property.String('test', 'true');
176
- element.model = [p.toJSON()];
177
- assert.isFalse(spy.called);
178
- });
179
- });
180
-
181
- describe('values rendering', () => {
182
- let element: BodyFormdataEditorElement;
183
- beforeEach(async () => {
184
- const value = generator.http.payload.urlEncoded();
185
- element = await valueFixture(value);
186
- });
187
-
188
- it('renders form rows for each model entry', () => {
189
- const items = element.shadowRoot!.querySelectorAll('.param-row');
190
- assert.lengthOf(items, element.model.length);
191
- });
192
-
193
- it('renders the enable switch', () => {
194
- const item = element.shadowRoot!.querySelector('.param-row ui-switch');
195
- assert.ok(item);
196
- });
197
-
198
- it('renders the remove button', () => {
199
- const item = element.shadowRoot!.querySelector('.param-row ui-icon-button');
200
- assert.ok(item);
201
- });
202
-
203
- it('renders the name input', () => {
204
- const item = element.shadowRoot!.querySelector('.param-row .name-input input');
205
- assert.ok(item);
206
- });
207
-
208
- it('renders the value input', () => {
209
- const item = element.shadowRoot!.querySelector('.param-row .value-input input');
210
- assert.ok(item);
211
- });
212
- });
213
-
214
- describe('enable/disable action', () => {
215
- let element: BodyFormdataEditorElement;
216
- beforeEach(async () => {
217
- const value = generator.http.payload.urlEncoded();
218
- element = await valueFixture(value);
219
- });
220
-
221
- it('disables the form item', () => {
222
- const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
223
- item.click();
224
- assert.isFalse(element.model[0].enabled);
225
- });
226
-
227
- it('updates the value', () => {
228
- const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
229
- item.click();
230
- const { name, value: modelValue } = element.model[0];
231
- const { value } = element;
232
- assert.notInclude(value, `${name}=${modelValue}`);
233
- });
234
-
235
- it('dispatches the change event', () => {
236
- const spy = sinon.spy();
237
- element.addEventListener('change', spy);
238
- const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
239
- item.click();
240
- assert.isTrue(spy.called);
241
- });
242
-
243
- it('re-enables the form item', async () => {
244
- const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
245
- item.click();
246
- await aTimeout(0);
247
- item.click();
248
- assert.isTrue(element.model[0].enabled);
249
- });
250
-
251
- it('changes the value when enabling', async () => {
252
- const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
253
- item.click();
254
- await aTimeout(0);
255
- item.click();
256
- const { name, value: modelValue } = element.model[0];
257
- const { value } = element;
258
- assert.include(value, `${name}=${modelValue}`);
259
- });
260
-
261
- it('dispatches the change event when enabling', async () => {
262
- const spy = sinon.spy();
263
- element.addEventListener('change', spy);
264
- const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
265
- item.click();
266
- await aTimeout(0);
267
- item.click();
268
- assert.equal(spy.callCount, 2);
269
- });
270
- });
271
-
272
- describe('removing an item', () => {
273
- let element: BodyFormdataEditorElement;
274
- beforeEach(async () => {
275
- const value = generator.http.payload.urlEncoded();
276
- element = await valueFixture(value);
277
- });
278
-
279
- it('removes an item from the model', () => {
280
- const item = { ...element.model[0] };
281
- const button = (element.shadowRoot!.querySelector('.param-row ui-icon-button')) as UiButtonElement;
282
- button.click();
283
- assert.notDeepEqual(element.model[0], item);
284
- });
285
-
286
- it('updates the value', () => {
287
- const item = { ...element.model[0] };
288
- const button = (element.shadowRoot!.querySelector('.param-row ui-icon-button')) as UiButtonElement;
289
- button.click();
290
- assert.notInclude(element.value, `${item.name}=${item.value}`);
291
- });
292
-
293
- it('dispatches the change event', () => {
294
- const spy = sinon.spy();
295
- element.addEventListener('change', spy);
296
- const button = (element.shadowRoot!.querySelector('.param-row ui-icon-button')) as UiButtonElement;
297
- button.click();
298
- assert.isTrue(spy.calledOnce);
299
- });
300
- });
301
-
302
- describe('name change', () => {
303
- let element: BodyFormdataEditorElement;
304
- beforeEach(async () => {
305
- const value = generator.http.payload.urlEncoded();
306
- element = await valueFixture(value);
307
- });
308
-
309
- it('changes the name', () => {
310
- const item = { ...element.model[0] };
311
- const input = (element.shadowRoot!.querySelector('.param-row .name-input input')) as HTMLInputElement;
312
- input.value = 'new-value-test';
313
- input.dispatchEvent(new CustomEvent('change'))
314
- assert.notEqual(element.model[0].name, item.name);
315
- assert.equal(element.model[0].name, 'new-value-test');
316
- });
317
-
318
- it('updates the value', () => {
319
- const input = (element.shadowRoot!.querySelector('.param-row .name-input input')) as HTMLInputElement;
320
- input.value = 'new-value-test';
321
- input.dispatchEvent(new CustomEvent('change'))
322
- assert.include(element.value, `new-value-test=${element.model[0].value}`);
323
- });
324
-
325
- it('dispatches the change event', () => {
326
- const spy = sinon.spy();
327
- element.addEventListener('change', spy);
328
- const input = (element.shadowRoot!.querySelector('.param-row .name-input input')) as HTMLInputElement;
329
- input.value = 'new-value-test';
330
- input.dispatchEvent(new CustomEvent('change'))
331
- assert.isTrue(spy.calledOnce);
332
- });
333
- });
334
-
335
- describe('value change', () => {
336
- let element: BodyFormdataEditorElement;
337
- beforeEach(async () => {
338
- const value = generator.http.payload.urlEncoded();
339
- element = await valueFixture(value);
340
- });
341
-
342
- it('changes the value', () => {
343
- const item = { ...element.model[0] };
344
- const input = (element.shadowRoot!.querySelector('.param-row .value-input input')) as HTMLInputElement;
345
- input.value = 'new-value-test';
346
- input.dispatchEvent(new CustomEvent('change'))
347
- assert.notEqual(element.model[0].value, item.value);
348
- assert.equal(element.model[0].value, 'new-value-test');
349
- });
350
-
351
- it('updates the value', () => {
352
- const input = (element.shadowRoot!.querySelector('.param-row .value-input input')) as HTMLInputElement;
353
- input.value = 'new-value-test';
354
- input.dispatchEvent(new CustomEvent('change'))
355
- assert.include(element.value, `${element.model[0].name}=new-value-test`);
356
- });
357
-
358
- it('dispatches the change event', () => {
359
- const spy = sinon.spy();
360
- element.addEventListener('change', spy);
361
- const input = (element.shadowRoot!.querySelector('.param-row .value-input input')) as HTMLInputElement;
362
- input.value = 'new-value-test';
363
- input.dispatchEvent(new CustomEvent('change'))
364
- assert.isTrue(spy.calledOnce);
365
- });
366
- });
367
-
368
- describe('value encoding', () => {
369
- let element: BodyFormdataEditorElement;
370
- beforeEach(async () => {
371
- const value = 'a b=c d'
372
- element = await valueFixture(value);
373
- });
374
-
375
- it('has unchanged values in the model', () => {
376
- const [item] = element.model;
377
- assert.equal(item.name, 'a b');
378
- assert.equal(item.value, 'c d');
379
- });
380
-
381
- it('encodes the model values', () => {
382
- element.encodeParameters();
383
- const [item] = element.model;
384
- assert.equal(item.name, 'a+b');
385
- assert.equal(item.value, 'c+d');
386
- });
387
-
388
- it('encodes the value', () => {
389
- element.encodeParameters();
390
- assert.equal(element.value, 'a+b=c+d');
391
- });
392
-
393
- it('dispatches the change event', () => {
394
- const spy = sinon.spy();
395
- element.addEventListener('change', spy);
396
- element.encodeParameters();
397
- assert.isTrue(spy.calledOnce);
398
- });
399
- });
400
-
401
- describe('value decoding', () => {
402
- let element: BodyFormdataEditorElement;
403
- beforeEach(async () => {
404
- const value = 'a+b=c+d'
405
- element = await valueFixture(value);
406
- });
407
-
408
- it('has unchanged values in the model', () => {
409
- const [item] = element.model;
410
- assert.equal(item.name, 'a+b');
411
- assert.equal(item.value, 'c+d');
412
- });
413
-
414
- it('decodes the model values', () => {
415
- element.decodeParameters();
416
- const [item] = element.model;
417
- assert.equal(item.name, 'a b');
418
- assert.equal(item.value, 'c d');
419
- });
420
-
421
- it('decodes the value', () => {
422
- element.decodeParameters();
423
- assert.equal(element.value, 'a b=c d');
424
- });
425
-
426
- it('dispatches the change event', () => {
427
- const spy = sinon.spy();
428
- element.addEventListener('change', spy);
429
- element.decodeParameters();
430
- assert.isTrue(spy.calledOnce);
431
- });
432
- });
433
-
434
- describe('#autoEncode', () => {
435
- let element: BodyFormdataEditorElement;
436
- beforeEach(async () => { element = await autoEncodeFixture(); });
437
-
438
- it('automatically decodes the set value', () => {
439
- element.value = 'a+b=c+d';
440
- const [item] = element.model;
441
- assert.equal(item.name, 'a b');
442
- assert.equal(item.value, 'c d');
443
- });
444
-
445
- it('encodes values on input change', async () => {
446
- element.value = 'a+b=c+d';
447
- await nextFrame();
448
- const input = (element.shadowRoot!.querySelector('.param-row .name-input input')) as HTMLInputElement;
449
- input.value = 'new value test';
450
- input.dispatchEvent(new CustomEvent('change'))
451
- assert.equal(element.value, 'new+value+test=c+d');
452
- });
453
-
454
- it('does not double encodes values', async () => {
455
- element.value = 'a+b=c+d';
456
- await nextFrame();
457
- const input = (element.shadowRoot!.querySelector('.param-row .name-input input')) as HTMLInputElement;
458
- input.value = 'new value test';
459
- input.dispatchEvent(new CustomEvent('change'))
460
- await nextFrame();
461
- input.value = 'new value tests';
462
- input.dispatchEvent(new CustomEvent('change'))
463
- assert.equal(element.value, 'new+value+tests=c+d');
10
+ describe('elements', () => {
11
+ describe('http', () => {
12
+ describe('BodyUrlEncodedEditor', () => {
13
+ async function basicFixture(): Promise<BodyFormdataEditorElement> {
14
+ return fixture(html`<http-body-urlencoded-editor allowFormInfo></http-body-urlencoded-editor>`);
15
+ }
16
+
17
+ async function valueFixture(value: string): Promise<BodyFormdataEditorElement> {
18
+ return fixture(html`<http-body-urlencoded-editor .value="${value}" allowFormInfo></http-body-urlencoded-editor>`);
19
+ }
20
+
21
+ async function autoEncodeFixture(): Promise<BodyFormdataEditorElement> {
22
+ return fixture(html`<http-body-urlencoded-editor autoEncode allowFormInfo></http-body-urlencoded-editor>`);
23
+ }
24
+
25
+ const generator = new ProjectMock();
26
+
27
+ before(async () => loadMonaco());
28
+
29
+ describe('Empty state', () => {
30
+ let element: BodyFormdataEditorElement;
31
+ beforeEach(async () => { element = await basicFixture(); })
32
+
33
+ it('renders empty message', () => {
34
+ const node = element.shadowRoot!.querySelector('.empty-message');
35
+ assert.ok(node);
36
+ });
37
+
38
+ it('renders the form mime information', () => {
39
+ const node = element.shadowRoot!.querySelector('.form-info');
40
+ assert.ok(node);
41
+ });
42
+
43
+ it('has empty model', () => {
44
+ assert.deepEqual(element.model, []);
45
+ });
46
+ });
47
+
48
+ describe('adding a property', () => {
49
+ let element: BodyFormdataEditorElement;
50
+ beforeEach(async () => { element = await basicFixture(); })
51
+
52
+ it('adds a model item on add button click', () => {
53
+ element.addParameter();
54
+ assert.lengthOf(element.model, 1);
55
+ });
56
+
57
+ it('does not add a model when readonly', () => {
58
+ element.readOnly = true;
59
+ element.addParameter();
60
+ assert.lengthOf(element.model, 0);
61
+ });
62
+
63
+ it('does not add a model when disabled', () => {
64
+ element.disabled = true;
65
+ element.addParameter();
66
+ assert.lengthOf(element.model, 0);
67
+ });
68
+
69
+ it('model item has basic schema', () => {
70
+ element.addParameter();
71
+ const p = Property.String();
72
+ assert.deepEqual(element.model[0], p.toJSON());
73
+ });
74
+
75
+ it('adds an item with undefined model', () => {
76
+ // @ts-ignore
77
+ element.model = undefined;
78
+ element.addParameter();
79
+ assert.lengthOf(element.model, 1);
80
+ });
81
+
82
+ it('focuses on the added item', async () => {
83
+ const spy = sinon.spy(element, 'focusLast');
84
+ element.addParameter();
85
+ await aTimeout(0);
86
+ assert.isTrue(spy.called);
87
+ });
88
+
89
+ it('does not notify model change', async () => {
90
+ // there's no point of storing the model without empty values. They are not generating
91
+ // any editor value
92
+ const spy = sinon.spy();
93
+ element.addEventListener('change', spy);
94
+ element.addParameter();
95
+ assert.isFalse(spy.called);
96
+ });
97
+ });
98
+
99
+ describe('#value', () => {
100
+ let element: BodyFormdataEditorElement;
101
+ beforeEach(async () => { element = await basicFixture(); })
102
+
103
+ it('reads set value', () => {
104
+ element.value = 'a=b';
105
+ assert.equal(element.value, 'a=b');
106
+ });
107
+
108
+ it('generates a view model', () => {
109
+ element.value = 'a=b&c=d';
110
+ assert.lengthOf(element.model, 2);
111
+ });
112
+
113
+ it('generated model has basic properties', () => {
114
+ element.value = 'a=b&c=d';
115
+ const [item] = element.model;
116
+ const p = Property.String('a', 'b');
117
+ assert.deepEqual(item, p.toJSON());
118
+ });
119
+
120
+ it('clears the model when no value', () => {
121
+ element.value = 'a=b&c=d';
122
+ assert.lengthOf(element.model, 2);
123
+ element.value = '';
124
+ assert.lengthOf(element.model, 0);
125
+ });
126
+
127
+ it('updates existing model', () => {
128
+ const p = Property.String('test', 'true');
129
+ element.model = [p.toJSON()];
130
+ element.value = 'a=b&c=d';
131
+ assert.equal(element.model[0].name, 'a');
132
+ });
133
+
134
+ it('does not notify model change', async () => {
135
+ // value/model setters should not dispatch change events
136
+ const spy = sinon.spy();
137
+ element.addEventListener('change', spy);
138
+ element.value = 'a=b&c=d';
139
+ assert.isFalse(spy.called);
140
+ });
141
+ });
142
+
143
+ describe('#model', () => {
144
+ let element: BodyFormdataEditorElement;
145
+ beforeEach(async () => { element = await basicFixture(); })
146
+
147
+ it('reads set value', () => {
148
+ const p = Property.String('test', 'true');
149
+ element.model = [p.toJSON()];
150
+ assert.deepEqual(element.model, [p.toJSON()]);
151
+ });
152
+
153
+ it('generates a value', () => {
154
+ const p = Property.String('test', 'true');
155
+ element.model = [p.toJSON()];
156
+ assert.equal(element.value, 'test=true');
157
+ });
158
+
159
+ it('clears the previously set value', () => {
160
+ element.value = 'a=b&c=d';
161
+ // @ts-ignore
162
+ element.model = undefined;
163
+ assert.equal(element.value, '');
164
+ });
165
+
166
+ it('updates existing value', () => {
167
+ element.value = 'a=b&c=d';
168
+ const p = Property.String('test', 'true');
169
+ element.model = [p.toJSON()];
170
+ assert.equal(element.value, 'test=true');
171
+ });
172
+
173
+ it('does not notify model change', () => {
174
+ // value/model setters should not dispatch change events
175
+ const spy = sinon.spy();
176
+ element.addEventListener('change', spy);
177
+ const p = Property.String('test', 'true');
178
+ element.model = [p.toJSON()];
179
+ assert.isFalse(spy.called);
180
+ });
181
+ });
182
+
183
+ describe('values rendering', () => {
184
+ let element: BodyFormdataEditorElement;
185
+ beforeEach(async () => {
186
+ const value = generator.http.payload.urlEncoded();
187
+ element = await valueFixture(value);
188
+ });
189
+
190
+ it('renders form rows for each model entry', () => {
191
+ const items = element.shadowRoot!.querySelectorAll('.param-row');
192
+ assert.lengthOf(items, element.model.length);
193
+ });
194
+
195
+ it('renders the enable switch', () => {
196
+ const item = element.shadowRoot!.querySelector('.param-row ui-switch');
197
+ assert.ok(item);
198
+ });
199
+
200
+ it('renders the remove button', () => {
201
+ const item = element.shadowRoot!.querySelector('.param-row ui-icon-button');
202
+ assert.ok(item);
203
+ });
204
+
205
+ it('renders the name input', () => {
206
+ const item = element.shadowRoot!.querySelector('.param-row .name-input input');
207
+ assert.ok(item);
208
+ });
209
+
210
+ it('renders the value input', () => {
211
+ const item = element.shadowRoot!.querySelector('.param-row .value-input input');
212
+ assert.ok(item);
213
+ });
214
+ });
215
+
216
+ describe('enable/disable action', () => {
217
+ let element: BodyFormdataEditorElement;
218
+ beforeEach(async () => {
219
+ const value = generator.http.payload.urlEncoded();
220
+ element = await valueFixture(value);
221
+ });
222
+
223
+ it('disables the form item', () => {
224
+ const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
225
+ item.click();
226
+ assert.isFalse(element.model[0].enabled);
227
+ });
228
+
229
+ it('updates the value', () => {
230
+ const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
231
+ item.click();
232
+ const { name, value: modelValue } = element.model[0];
233
+ const { value } = element;
234
+ assert.notInclude(value, `${name}=${modelValue}`);
235
+ });
236
+
237
+ it('dispatches the change event', () => {
238
+ const spy = sinon.spy();
239
+ element.addEventListener('change', spy);
240
+ const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
241
+ item.click();
242
+ assert.isTrue(spy.called);
243
+ });
244
+
245
+ it('re-enables the form item', async () => {
246
+ const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
247
+ item.click();
248
+ await aTimeout(0);
249
+ item.click();
250
+ assert.isTrue(element.model[0].enabled);
251
+ });
252
+
253
+ it('changes the value when enabling', async () => {
254
+ const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
255
+ item.click();
256
+ await aTimeout(0);
257
+ item.click();
258
+ const { name, value: modelValue } = element.model[0];
259
+ const { value } = element;
260
+ assert.include(value, `${name}=${modelValue}`);
261
+ });
262
+
263
+ it('dispatches the change event when enabling', async () => {
264
+ const spy = sinon.spy();
265
+ element.addEventListener('change', spy);
266
+ const item = (element.shadowRoot!.querySelector('.param-row ui-switch')) as SwitchElement;
267
+ item.click();
268
+ await aTimeout(0);
269
+ item.click();
270
+ assert.equal(spy.callCount, 2);
271
+ });
272
+ });
273
+
274
+ describe('removing an item', () => {
275
+ let element: BodyFormdataEditorElement;
276
+ beforeEach(async () => {
277
+ const value = generator.http.payload.urlEncoded();
278
+ element = await valueFixture(value);
279
+ });
280
+
281
+ it('removes an item from the model', () => {
282
+ const item = { ...element.model[0] };
283
+ const button = (element.shadowRoot!.querySelector('.param-row ui-icon-button')) as UiButtonElement;
284
+ button.click();
285
+ assert.notDeepEqual(element.model[0], item);
286
+ });
287
+
288
+ it('updates the value', () => {
289
+ const item = { ...element.model[0] };
290
+ const button = (element.shadowRoot!.querySelector('.param-row ui-icon-button')) as UiButtonElement;
291
+ button.click();
292
+ assert.notInclude(element.value, `${item.name}=${item.value}`);
293
+ });
294
+
295
+ it('dispatches the change event', () => {
296
+ const spy = sinon.spy();
297
+ element.addEventListener('change', spy);
298
+ const button = (element.shadowRoot!.querySelector('.param-row ui-icon-button')) as UiButtonElement;
299
+ button.click();
300
+ assert.isTrue(spy.calledOnce);
301
+ });
302
+ });
303
+
304
+ describe('name change', () => {
305
+ let element: BodyFormdataEditorElement;
306
+ beforeEach(async () => {
307
+ const value = generator.http.payload.urlEncoded();
308
+ element = await valueFixture(value);
309
+ });
310
+
311
+ it('changes the name', () => {
312
+ const item = { ...element.model[0] };
313
+ const input = (element.shadowRoot!.querySelector('.param-row .name-input input')) as HTMLInputElement;
314
+ input.value = 'new-value-test';
315
+ input.dispatchEvent(new CustomEvent('change'))
316
+ assert.notEqual(element.model[0].name, item.name);
317
+ assert.equal(element.model[0].name, 'new-value-test');
318
+ });
319
+
320
+ it('updates the value', () => {
321
+ const input = (element.shadowRoot!.querySelector('.param-row .name-input input')) as HTMLInputElement;
322
+ input.value = 'new-value-test';
323
+ input.dispatchEvent(new CustomEvent('change'))
324
+ assert.include(element.value, `new-value-test=${element.model[0].value}`);
325
+ });
326
+
327
+ it('dispatches the change event', () => {
328
+ const spy = sinon.spy();
329
+ element.addEventListener('change', spy);
330
+ const input = (element.shadowRoot!.querySelector('.param-row .name-input input')) as HTMLInputElement;
331
+ input.value = 'new-value-test';
332
+ input.dispatchEvent(new CustomEvent('change'))
333
+ assert.isTrue(spy.calledOnce);
334
+ });
335
+ });
336
+
337
+ describe('value change', () => {
338
+ let element: BodyFormdataEditorElement;
339
+ beforeEach(async () => {
340
+ const value = generator.http.payload.urlEncoded();
341
+ element = await valueFixture(value);
342
+ });
343
+
344
+ it('changes the value', () => {
345
+ const item = { ...element.model[0] };
346
+ const input = (element.shadowRoot!.querySelector('.param-row .value-input input')) as HTMLInputElement;
347
+ input.value = 'new-value-test';
348
+ input.dispatchEvent(new CustomEvent('change'))
349
+ assert.notEqual(element.model[0].value, item.value);
350
+ assert.equal(element.model[0].value, 'new-value-test');
351
+ });
352
+
353
+ it('updates the value', () => {
354
+ const input = (element.shadowRoot!.querySelector('.param-row .value-input input')) as HTMLInputElement;
355
+ input.value = 'new-value-test';
356
+ input.dispatchEvent(new CustomEvent('change'))
357
+ assert.include(element.value, `${element.model[0].name}=new-value-test`);
358
+ });
359
+
360
+ it('dispatches the change event', () => {
361
+ const spy = sinon.spy();
362
+ element.addEventListener('change', spy);
363
+ const input = (element.shadowRoot!.querySelector('.param-row .value-input input')) as HTMLInputElement;
364
+ input.value = 'new-value-test';
365
+ input.dispatchEvent(new CustomEvent('change'))
366
+ assert.isTrue(spy.calledOnce);
367
+ });
368
+ });
369
+
370
+ describe('value encoding', () => {
371
+ let element: BodyFormdataEditorElement;
372
+ beforeEach(async () => {
373
+ const value = 'a b=c d'
374
+ element = await valueFixture(value);
375
+ });
376
+
377
+ it('has unchanged values in the model', () => {
378
+ const [item] = element.model;
379
+ assert.equal(item.name, 'a b');
380
+ assert.equal(item.value, 'c d');
381
+ });
382
+
383
+ it('encodes the model values', () => {
384
+ element.encodeParameters();
385
+ const [item] = element.model;
386
+ assert.equal(item.name, 'a+b');
387
+ assert.equal(item.value, 'c+d');
388
+ });
389
+
390
+ it('encodes the value', () => {
391
+ element.encodeParameters();
392
+ assert.equal(element.value, 'a+b=c+d');
393
+ });
394
+
395
+ it('dispatches the change event', () => {
396
+ const spy = sinon.spy();
397
+ element.addEventListener('change', spy);
398
+ element.encodeParameters();
399
+ assert.isTrue(spy.calledOnce);
400
+ });
401
+ });
402
+
403
+ describe('value decoding', () => {
404
+ let element: BodyFormdataEditorElement;
405
+ beforeEach(async () => {
406
+ const value = 'a+b=c+d'
407
+ element = await valueFixture(value);
408
+ });
409
+
410
+ it('has unchanged values in the model', () => {
411
+ const [item] = element.model;
412
+ assert.equal(item.name, 'a+b');
413
+ assert.equal(item.value, 'c+d');
414
+ });
415
+
416
+ it('decodes the model values', () => {
417
+ element.decodeParameters();
418
+ const [item] = element.model;
419
+ assert.equal(item.name, 'a b');
420
+ assert.equal(item.value, 'c d');
421
+ });
422
+
423
+ it('decodes the value', () => {
424
+ element.decodeParameters();
425
+ assert.equal(element.value, 'a b=c d');
426
+ });
427
+
428
+ it('dispatches the change event', () => {
429
+ const spy = sinon.spy();
430
+ element.addEventListener('change', spy);
431
+ element.decodeParameters();
432
+ assert.isTrue(spy.calledOnce);
433
+ });
434
+ });
435
+
436
+ describe('#autoEncode', () => {
437
+ let element: BodyFormdataEditorElement;
438
+ beforeEach(async () => { element = await autoEncodeFixture(); });
439
+
440
+ it('automatically decodes the set value', () => {
441
+ element.value = 'a+b=c+d';
442
+ const [item] = element.model;
443
+ assert.equal(item.name, 'a b');
444
+ assert.equal(item.value, 'c d');
445
+ });
446
+
447
+ it('encodes values on input change', async () => {
448
+ element.value = 'a+b=c+d';
449
+ await nextFrame();
450
+ const input = (element.shadowRoot!.querySelector('.param-row .name-input input')) as HTMLInputElement;
451
+ input.value = 'new value test';
452
+ input.dispatchEvent(new CustomEvent('change'))
453
+ assert.equal(element.value, 'new+value+test=c+d');
454
+ });
455
+
456
+ it('does not double encodes values', async () => {
457
+ element.value = 'a+b=c+d';
458
+ await nextFrame();
459
+ const input = (element.shadowRoot!.querySelector('.param-row .name-input input')) as HTMLInputElement;
460
+ input.value = 'new value test';
461
+ input.dispatchEvent(new CustomEvent('change'))
462
+ await nextFrame();
463
+ input.value = 'new value tests';
464
+ input.dispatchEvent(new CustomEvent('change'))
465
+ assert.equal(element.value, 'new+value+tests=c+d');
466
+ });
467
+ });
464
468
  });
465
469
  });
466
470
  });