@atlassian/atlassian-connect-js 5.3.190

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 (190) hide show
  1. package/.depcheckrc.json +16 -0
  2. package/.editorconfig +9 -0
  3. package/.envrc +5 -0
  4. package/.eslintignore +12 -0
  5. package/.eslintrc +31 -0
  6. package/.husky/pre-commit +11 -0
  7. package/.lintstagedrc.js +6 -0
  8. package/.netrc +1 -0
  9. package/.npmrc-public +4 -0
  10. package/.nvmrc +1 -0
  11. package/LICENSE +3 -0
  12. package/README.md +281 -0
  13. package/bitbucket-pipelines.yml +33 -0
  14. package/build/bin/bin-helper.js +29 -0
  15. package/build/bin/npm-postinstall.js +9 -0
  16. package/build/configs/append-sourcemapping.js +13 -0
  17. package/build/configs/availabletasks.js +15 -0
  18. package/build/configs/clean.js +12 -0
  19. package/build/configs/concat.js +44 -0
  20. package/build/configs/copy.js +32 -0
  21. package/build/configs/index.js +19 -0
  22. package/build/configs/jshint.js +9 -0
  23. package/build/configs/karma.js +11 -0
  24. package/build/configs/replace.js +10 -0
  25. package/build/configs/requirejs.js +187 -0
  26. package/build/configs/saucelabs-launchers.js +30 -0
  27. package/build/configs/shell.js +24 -0
  28. package/build/configs/uglify.js +15 -0
  29. package/build/configs/watch.js +45 -0
  30. package/build/end.frag +13 -0
  31. package/build/start.frag +18 -0
  32. package/bundlesize.config.json +14 -0
  33. package/dist/connect-host.css +225 -0
  34. package/dist/connect-host.js +13908 -0
  35. package/dist/connect-host.min.css +1 -0
  36. package/dist/iframe-fedramp.js +13663 -0
  37. package/dist/iframe.js +13663 -0
  38. package/dist/legacy-text-colors.css +245 -0
  39. package/dist/surfaces.css +11 -0
  40. package/dist/themes/atlaskit-tokens_dark-future.css +6 -0
  41. package/dist/themes/atlaskit-tokens_dark.css +394 -0
  42. package/dist/themes/atlaskit-tokens_legacy-dark.css +394 -0
  43. package/dist/themes/atlaskit-tokens_legacy-light.css +394 -0
  44. package/dist/themes/atlaskit-tokens_light-future.css +6 -0
  45. package/dist/themes/atlaskit-tokens_light.css +394 -0
  46. package/dist/themes/atlaskit-tokens_shape.css +14 -0
  47. package/dist/themes/atlaskit-tokens_spacing.css +26 -0
  48. package/dist/themes/atlaskit-tokens_typography-adg3.css +25 -0
  49. package/dist/themes/atlaskit-tokens_typography-modernized.css +25 -0
  50. package/dist/themes/atlaskit-tokens_typography-refreshed.css +25 -0
  51. package/gulpfile.js +204 -0
  52. package/memleak-check/app.html +10 -0
  53. package/memleak-check/index.html +31 -0
  54. package/memleak-check/index.js +33 -0
  55. package/package.json +102 -0
  56. package/renovate.json +11 -0
  57. package/security-assistant.yml +2 -0
  58. package/spec/.eslintrc +10 -0
  59. package/spec/config/karma.base.conf.js +200 -0
  60. package/spec/config/karma.conf.js +20 -0
  61. package/spec/fixtures/base_dialog_component_tests.js +180 -0
  62. package/spec/mocks/mock_feature_flag.js +23 -0
  63. package/spec/tests/amd_spec.js +122 -0
  64. package/spec/tests/analytics_dispatcher_spec.js +429 -0
  65. package/spec/tests/analytics_performance_spec.js +41 -0
  66. package/spec/tests/button_spec.js +143 -0
  67. package/spec/tests/dialog_extension_spec.js +59 -0
  68. package/spec/tests/dialog_module_provider_spec.js +499 -0
  69. package/spec/tests/dialog_module_spec.js +395 -0
  70. package/spec/tests/dialog_spec.js +296 -0
  71. package/spec/tests/dialog_webitem_spec.js +183 -0
  72. package/spec/tests/dropdown_module_spec.js +77 -0
  73. package/spec/tests/env_module_spec.js +153 -0
  74. package/spec/tests/events_spec.js +77 -0
  75. package/spec/tests/extension_configuration_options_store_spec.js +25 -0
  76. package/spec/tests/flag_module_provider_spec.js +79 -0
  77. package/spec/tests/flag_module_spec.js +118 -0
  78. package/spec/tests/flag_spec.js +243 -0
  79. package/spec/tests/host-api_spec.js +220 -0
  80. package/spec/tests/iframe-create_spec.js +43 -0
  81. package/spec/tests/iframe_container_spec.js +19 -0
  82. package/spec/tests/iframe_spec.js +265 -0
  83. package/spec/tests/inline_dialog_spec.js +41 -0
  84. package/spec/tests/inline_dialog_webitem_spec.js +331 -0
  85. package/spec/tests/loading_indicator_spec.js +48 -0
  86. package/spec/tests/messages_module_spec.js +108 -0
  87. package/spec/tests/meta_spec.js +71 -0
  88. package/spec/tests/module_args_spec.js +52 -0
  89. package/spec/tests/observe_spec.js +73 -0
  90. package/spec/tests/public_events.spec.js +102 -0
  91. package/spec/tests/scroll_position_spec.js +109 -0
  92. package/spec/tests/theming_spec.js +594 -0
  93. package/spec/tests/util_spec.js +55 -0
  94. package/spec/tests/utils/base64_spec.js +20 -0
  95. package/spec/tests/utils/button_spec.js +11 -0
  96. package/spec/tests/utils/cookie_spec.js +19 -0
  97. package/spec/tests/utils/deprecate_spec.js +22 -0
  98. package/spec/tests/utils/dialog_spec.js +297 -0
  99. package/spec/tests/utils/host_util_spec.js +45 -0
  100. package/spec/tests/utils/iframe_spec.js +41 -0
  101. package/spec/tests/utils/jwt_spec.js +135 -0
  102. package/spec/tests/utils/url_spec.js +37 -0
  103. package/spec/tests/utils/waitUntilReadyNextTick.js +5 -0
  104. package/spec/tests/utils/webitem.js +219 -0
  105. package/spec/tests/webitem_spec.js +131 -0
  106. package/src/css/host/dialog.css +144 -0
  107. package/src/css/host/flags.css +5 -0
  108. package/src/css/host/host.css +64 -0
  109. package/src/css/host/messages.css +12 -0
  110. package/src/css/plugin/legacy-text-colors.less +55 -0
  111. package/src/css/plugin/surfaces.css +11 -0
  112. package/src/host/ACJSFrameworkAdaptor.js +44 -0
  113. package/src/host/actions/analytics_action.js +35 -0
  114. package/src/host/actions/button_actions.js +21 -0
  115. package/src/host/actions/dialog_actions.js +27 -0
  116. package/src/host/actions/dialog_extension_actions.js +25 -0
  117. package/src/host/actions/dom_event_actions.js +32 -0
  118. package/src/host/actions/dropdown_actions.js +12 -0
  119. package/src/host/actions/env_actions.js +57 -0
  120. package/src/host/actions/event_actions.js +33 -0
  121. package/src/host/actions/flag_actions.js +22 -0
  122. package/src/host/actions/iframe_actions.js +27 -0
  123. package/src/host/actions/inline_dialog_actions.js +26 -0
  124. package/src/host/actions/inline_dialog_webitem_actions.js +10 -0
  125. package/src/host/actions/jwt_actions.js +51 -0
  126. package/src/host/actions/loading_indicator_actions.js +10 -0
  127. package/src/host/actions/module_actions.js +14 -0
  128. package/src/host/actions/webitem_actions.js +29 -0
  129. package/src/host/components/button.js +112 -0
  130. package/src/host/components/dialog.js +447 -0
  131. package/src/host/components/dialog_extension.js +106 -0
  132. package/src/host/components/dialog_webitem.js +69 -0
  133. package/src/host/components/flag.js +102 -0
  134. package/src/host/components/iframe.js +130 -0
  135. package/src/host/components/iframe_container.js +38 -0
  136. package/src/host/components/inline_dialog.js +108 -0
  137. package/src/host/components/inline_dialog_webitem.js +157 -0
  138. package/src/host/components/loading_indicator.js +110 -0
  139. package/src/host/components/webitem.js +227 -0
  140. package/src/host/deprecate.js +20 -0
  141. package/src/host/dispatchers/analytics_dispatcher.js +512 -0
  142. package/src/host/dispatchers/event_dispatcher.js +46 -0
  143. package/src/host/dollar.js +8 -0
  144. package/src/host/host-api.js +325 -0
  145. package/src/host/iframe-create.js +7 -0
  146. package/src/host/index.js +108 -0
  147. package/src/host/module-providers.js +13 -0
  148. package/src/host/modules/_featureFlag.js +42 -0
  149. package/src/host/modules/_performance.js +54 -0
  150. package/src/host/modules/analytics.js +17 -0
  151. package/src/host/modules/dialog.js +496 -0
  152. package/src/host/modules/dropdown.js +255 -0
  153. package/src/host/modules/env.js +156 -0
  154. package/src/host/modules/events.js +28 -0
  155. package/src/host/modules/flag.js +170 -0
  156. package/src/host/modules/host.js +19 -0
  157. package/src/host/modules/inline-dialog.js +33 -0
  158. package/src/host/modules/messages.js +309 -0
  159. package/src/host/modules/page.js +29 -0
  160. package/src/host/modules/scroll-position.js +102 -0
  161. package/src/host/modules/theming.js +114 -0
  162. package/src/host/stores/extension_configuration_options_store.js +24 -0
  163. package/src/host/util.js +98 -0
  164. package/src/host/utils/access-narrowing-context.js +18 -0
  165. package/src/host/utils/base64.js +22 -0
  166. package/src/host/utils/button.js +10 -0
  167. package/src/host/utils/cookie.js +14 -0
  168. package/src/host/utils/dialog.js +239 -0
  169. package/src/host/utils/feature-flag.js +27 -0
  170. package/src/host/utils/iframe.js +23 -0
  171. package/src/host/utils/jwt.js +60 -0
  172. package/src/host/utils/observe.js +34 -0
  173. package/src/host/utils/removal-observer.js +30 -0
  174. package/src/host/utils/simplexdm.js +58 -0
  175. package/src/host/utils/url.js +23 -0
  176. package/src/host/utils/webitem.js +214 -0
  177. package/src/plugin/amd.js +115 -0
  178. package/src/plugin/analytics.js +84 -0
  179. package/src/plugin/deprecate.js +16 -0
  180. package/src/plugin/dialog.js +197 -0
  181. package/src/plugin/dollar.js +77 -0
  182. package/src/plugin/events-instance.js +2 -0
  183. package/src/plugin/events.js +246 -0
  184. package/src/plugin/extension_configuration_options_store.js +27 -0
  185. package/src/plugin/featureFlag.js +8 -0
  186. package/src/plugin/index.js +118 -0
  187. package/src/plugin/meta.js +14 -0
  188. package/src/plugin/public-events.js +73 -0
  189. package/src/plugin/theming.js +211 -0
  190. package/src/plugin/util.js +104 -0
@@ -0,0 +1,118 @@
1
+ import FlagModule from 'src/host/modules/flag';
2
+ import EventDispatcher from 'src/host/dispatchers/event_dispatcher';
3
+ import EventActions from 'src/host/actions/event_actions';
4
+
5
+ describe('flag api module', () => {
6
+
7
+ afterEach(() => {
8
+ $('.aui-flag').remove();
9
+ });
10
+
11
+ it('should return the flag api the correct methods', () => {
12
+ expect(Object.getOwnPropertyNames(FlagModule)).toEqual(['create']);
13
+ expect(Object.getOwnPropertyNames(FlagModule.create)).toEqual(['constructor', 'close']);
14
+ });
15
+
16
+ describe('constructor', () => {
17
+ it('should create a flag', (done) => {
18
+
19
+ EventDispatcher.registerOnce('flag-open', (e) => {
20
+ expect(e.id).toEqual('ap-flag-abc123');
21
+ expect($('#' + e.id).hasClass('aui-flag')).toBe(true);
22
+ expect($('#' + e.id).find('.title').text()).toEqual('some title');
23
+ expect($('#' + e.id).find('.ac-flag-actions a').text()).toEqual('action text');
24
+ done();
25
+ });
26
+
27
+ var flagCallback = function(){};
28
+ flagCallback._id = 'abc123';
29
+ flagCallback._context = {
30
+ extension: {
31
+ id: 'an-extension-id'
32
+ }
33
+ };
34
+ new FlagModule.create.constructor({
35
+ type: 'success',
36
+ title: 'some title',
37
+ body: 'the body',
38
+ actions: {
39
+ key: 'action text'
40
+ }
41
+ }, flagCallback);
42
+
43
+ });
44
+ });
45
+
46
+ describe('action', () => {
47
+ it('should trigger an event on click', () =>{
48
+ var flagCallback = function(){};
49
+ flagCallback._id = 'a1';
50
+ flagCallback._context = {
51
+ extension: {
52
+ id: 'an-extension-id'
53
+ }
54
+ };
55
+ var flag = new FlagModule.create.constructor({
56
+ type: 'success',
57
+ title: 'some title',
58
+ body: 'the body',
59
+ actions: {
60
+ akey: 'some value'
61
+ }
62
+ }, flagCallback);
63
+ expect($('.ac-flag-actions a').length).toEqual(1);
64
+ spyOn(EventActions,'broadcast');
65
+ expect(EventActions.broadcast).not.toHaveBeenCalled();
66
+ $('.ac-flag-actions a').click();
67
+ expect(EventActions.broadcast).toHaveBeenCalled();
68
+ expect(EventActions.broadcast).toHaveBeenCalledWith(
69
+ 'flag.action',
70
+ flagCallback._context.extension,
71
+ {
72
+ flagIdentifier: flagCallback._id,
73
+ actionIdentifier: 'akey'
74
+ });
75
+ });
76
+ });
77
+
78
+ describe('close', () => {
79
+ it('should close the flag', () =>{
80
+ var flagCallback = function(){};
81
+ flagCallback._id = 'abc1234';
82
+ flagCallback._context = {
83
+ extension: {}
84
+ };
85
+ var flag = new FlagModule.create.constructor({
86
+ type: 'success',
87
+ title: 'some title',
88
+ body: 'the body'
89
+ }, flagCallback);
90
+ expect($('.aui-flag').attr('aria-hidden')).toEqual('false');
91
+ flag.close(flagCallback);
92
+ expect($('.aui-flag').attr('aria-hidden')).toEqual('true');
93
+ });
94
+ });
95
+
96
+ describe('on close', () => {
97
+ it('should set an event hanler', () => {
98
+ var flagCallback = function(){};
99
+ flagCallback._id = 'abc1234';
100
+ flagCallback._context = {
101
+ extension: {
102
+ id: 'some-extension-id'
103
+ }
104
+ };
105
+ var flag = new FlagModule.create.constructor({
106
+ type: 'success',
107
+ title: 'some title',
108
+ body: 'the body'
109
+ }, flagCallback);
110
+ spyOn(EventActions,'broadcast');
111
+ expect(EventActions.broadcast).not.toHaveBeenCalled();
112
+ flag.close(flagCallback);
113
+ expect(EventActions.broadcast).toHaveBeenCalled();
114
+ expect(EventActions.broadcast).toHaveBeenCalledWith('flag.close', flagCallback._context.extension, { flagIdentifier: flagCallback._id });
115
+ });
116
+ });
117
+
118
+ });
@@ -0,0 +1,243 @@
1
+ import FlagComponent from 'src/host/components/flag';
2
+ import FlagActions from 'src/host/actions/flag_actions';
3
+
4
+ /**
5
+ * Because we have no idea when aui/flag will be available
6
+ * we have to make all these tests async whilst we wait for it.
7
+ */
8
+
9
+ describe('Flag Component', () => {
10
+
11
+ beforeEach(() => {
12
+ });
13
+
14
+ afterEach(() => {
15
+ $('.aui-flag').remove();
16
+ });
17
+
18
+ describe('close', () => {
19
+
20
+ it('the flag returns a close method', (done) => {
21
+ window.require(['aui/flag'], () => {
22
+ var $flag = FlagComponent.render({
23
+ id: 'some-id',
24
+ type: 'success',
25
+ body: 'hello world',
26
+ title: 'some title'
27
+ });
28
+ expect($('.aui-flag').attr('aria-hidden')).toEqual('false');
29
+ $flag.close();
30
+ expect($('.aui-flag').attr('aria-hidden')).toEqual('true');
31
+ done();
32
+ });
33
+ });
34
+
35
+
36
+ it('the close action closes the flag', (done) => {
37
+ window.require(['aui/flag'], () => {
38
+ var $flag = FlagComponent.render({
39
+ id: 'some-id',
40
+ type: 'success',
41
+ body: 'hello world',
42
+ title: 'some title'
43
+ });
44
+ expect($('.aui-flag').attr('aria-hidden')).toEqual('false');
45
+ FlagActions.close($flag.attr('id'));
46
+ expect($('.aui-flag').attr('aria-hidden')).toEqual('true');
47
+ done();
48
+ });
49
+ });
50
+
51
+ it('the close action closes the correct flag when multiple flags are open', (done) => {
52
+ window.require(['aui/flag'], () => {
53
+ var $flag = FlagComponent.render({
54
+ id: 'some-id',
55
+ type: 'success',
56
+ body: 'hello world',
57
+ title: 'some title'
58
+ });
59
+ var $flag2 = FlagComponent.render({
60
+ id: 'some-other-id',
61
+ type: 'success',
62
+ body: 'hello world 2',
63
+ title: 'some title 2'
64
+ });
65
+ var $flag3 = FlagComponent.render({
66
+ id: 'some-third-id',
67
+ type: 'success',
68
+ body: 'hello world 3',
69
+ title: 'some title 3'
70
+ });
71
+ expect($flag.attr('aria-hidden')).toEqual('false');
72
+ expect($flag2.attr('aria-hidden')).toEqual('false');
73
+ expect($flag3.attr('aria-hidden')).toEqual('false');
74
+ FlagActions.close($flag2.attr('id'));
75
+ expect($flag.attr('aria-hidden')).toEqual('false');
76
+ expect($flag2.attr('aria-hidden')).toEqual('true');
77
+ expect($flag3.attr('aria-hidden')).toEqual('false');
78
+ done();
79
+ });
80
+ });
81
+
82
+
83
+ });
84
+
85
+
86
+ describe('rendering', () => {
87
+
88
+ it('renders a flag', (done) => {
89
+ window.require(['aui/flag'], () => {
90
+ var $flag = FlagComponent.render({
91
+ id: 'some-id',
92
+ type: 'success',
93
+ body: 'hello world',
94
+ title: 'some title'
95
+ });
96
+ expect($flag.hasClass('aui-flag')).toBe(true);
97
+ expect($flag.attr('id')).toEqual('ap-flag-some-id');
98
+ done();
99
+ });
100
+ });
101
+
102
+ it('renders a html body', (done) => {
103
+ window.require(['aui/flag'], () => {
104
+ var $flag = FlagComponent.render({
105
+ id: 'some-id',
106
+ type: 'success',
107
+ body: 'hello <b>world</b>',
108
+ title: 'some title'
109
+ });
110
+ expect($flag.find('b').text()).toEqual('world');
111
+ done();
112
+ });
113
+ });
114
+
115
+ it('renders a html body from jQuery', (done) => {
116
+ window.require(['aui/flag'], () => {
117
+ var $flag = FlagComponent.render({
118
+ id: 'some-id',
119
+ type: 'success',
120
+ body: $('<p>hello <b>world</b></p>'),
121
+ title: 'some title'
122
+ });
123
+ expect($flag.find('b').text()).toEqual('world');
124
+ done();
125
+ });
126
+ });
127
+
128
+ it('renders a plain text title', (done) => {
129
+ window.require(['aui/flag'], () => {
130
+ var $flag = FlagComponent.render({
131
+ id: 'some-id',
132
+ type: 'success',
133
+ body: 'hello world',
134
+ title: 'some title'
135
+ });
136
+ expect($flag.find('.title').text()).toEqual('some title');
137
+ done();
138
+ });
139
+ });
140
+
141
+ it('escapes a html title', (done) => {
142
+ window.require(['aui/flag'], () => {
143
+ var $flag = FlagComponent.render({
144
+ id: 'some-id',
145
+ type: 'success',
146
+ body: 'hello world',
147
+ title: '<b>some title</b>'
148
+ });
149
+ expect($flag.find('.title b').length).toEqual(0);
150
+ done();
151
+ });
152
+ });
153
+
154
+ it('escapes a jQuery title', (done) => {
155
+ window.require(['aui/flag'], () => {
156
+ var $flag = FlagComponent.render({
157
+ id: 'some-id',
158
+ type: 'success',
159
+ body: 'hello world',
160
+ title: AJS.$('<b>some title</b>')
161
+ });
162
+ expect($flag.find('b').length).toEqual(0);
163
+ done();
164
+ });
165
+ });
166
+
167
+ it('renders an action', (done) => {
168
+ window.require(['aui/flag'], () => {
169
+ var $flag = FlagComponent.render({
170
+ id: 'some-id',
171
+ type: 'success',
172
+ body: 'hello world',
173
+ actions: {
174
+ akey: 'a value'
175
+ },
176
+ title: AJS.$('<b>some title</b>')
177
+ });
178
+ expect($flag.find('.ac-flag-actions a').length).toEqual(1);
179
+ expect($flag.find('.ac-flag-actions a').text()).toEqual('a value');
180
+ done();
181
+ });
182
+ });
183
+ it('renders multiple actions', (done) => {
184
+ window.require(['aui/flag'], () => {
185
+ var $flag = FlagComponent.render({
186
+ id: 'some-id',
187
+ type: 'success',
188
+ body: 'hello world',
189
+ actions: {
190
+ akey: 'a value',
191
+ anotherKey: 'another value'
192
+ },
193
+ title: AJS.$('<b>some title</b>')
194
+ });
195
+ expect($flag.find('.ac-flag-actions a').length).toEqual(2);
196
+ expect($flag.find('.ac-flag-actions a:first').text()).toEqual('a value');
197
+ expect($flag.find('.ac-flag-actions a:nth-child(2)').text()).toEqual('another value');
198
+ done();
199
+ });
200
+ });
201
+
202
+ it('triggers an event on action click', (done) => {
203
+ window.require(['aui/flag'], () => {
204
+ var $flag = FlagComponent.render({
205
+ id: 'some-id',
206
+ type: 'success',
207
+ body: 'hello world',
208
+ actions: {
209
+ akey: 'a value'
210
+ },
211
+ title: AJS.$('<b>some title</b>')
212
+ });
213
+ spyOn(FlagActions, 'actionInvoked');
214
+ expect(FlagActions.actionInvoked).not.toHaveBeenCalled();
215
+ $flag.find('.ac-flag-actions a').click();
216
+ expect(FlagActions.actionInvoked).toHaveBeenCalled();
217
+ expect(FlagActions.actionInvoked).toHaveBeenCalledWith('akey', 'some-id');
218
+ done();
219
+ });
220
+ });
221
+
222
+
223
+ it('escapes html in actions', (done) => {
224
+ var actions = {};
225
+ actions['<b>hello</b>'] = '<i>world</i>';
226
+ window.require(['aui/flag'], () => {
227
+ var $flag = FlagComponent.render({
228
+ id: 'some-id',
229
+ type: 'success',
230
+ body: 'hello world',
231
+ actions: actions,
232
+ title: AJS.$('<b>some title</b>')
233
+ });
234
+ expect($flag.find('.ac-flag-actions a').length).toEqual(1);
235
+ expect($flag.find('.ac-flag-actions a').html()).toEqual('&lt;i&gt;world&lt;/i&gt;');
236
+ expect($flag.find('.ac-flag-actions a').text()).toEqual('<i>world</i>');
237
+ done();
238
+ });
239
+ });
240
+
241
+ });
242
+
243
+ });
@@ -0,0 +1,220 @@
1
+ import HostApi from 'src/host/host-api';
2
+ import EventDispatcher from 'src/host/dispatchers/event_dispatcher';
3
+ import eventActions from 'src/host/actions/event_actions';
4
+ import simpleXDM from 'simple-xdm/host';
5
+
6
+ describe('Host API', function() {
7
+
8
+ it('onIframeEstablished binds', function() {
9
+ var spy = jasmine.createSpy('spy');
10
+ HostApi.onIframeEstablished(spy);
11
+ EventDispatcher.dispatch('after:iframe-bridge-established', {$el: AJS.$('<div />'), extension:{options:{}}});
12
+ expect(spy).toHaveBeenCalled();
13
+ });
14
+
15
+ it('onIframeUnload binds', function() {
16
+ var spy = jasmine.createSpy('spy');
17
+ HostApi.onIframeUnload(spy);
18
+ EventDispatcher.dispatch('after:iframe-unload', {extension:{}});
19
+ expect(spy).toHaveBeenCalled();
20
+ });
21
+
22
+ it('onEventDispatched binds', function(){
23
+ var spy = jasmine.createSpy('spy');
24
+ HostApi.onPublicEventDispatched(spy);
25
+ eventActions.broadcastPublic('a', {}, {
26
+ addon_key: 'abc',
27
+ key: '123'
28
+ });
29
+ expect(spy).toHaveBeenCalled();
30
+ HostApi.offPublicEventDispatched(spy);
31
+ });
32
+
33
+ it('broadcastPublic sanitises extension options for XDM including jwt tokens', function(){
34
+ spyOn(simpleXDM, 'dispatch');
35
+
36
+ var spy = jasmine.createSpy('spy');
37
+ HostApi.onPublicEventDispatched(spy);
38
+ const type = 'a';
39
+ const event = {};
40
+ const sanitisedExtension = {
41
+ addon_key: 'abc',
42
+ key: '123',
43
+ options: { }
44
+ };
45
+ const unsanitisedExtension = Object.assign({}, sanitisedExtension, {
46
+ options: {
47
+ some_func: function () {},
48
+ url: 'https://some.host.com/?jwt=secret',
49
+ contextJwt: 'secretJwtToken'
50
+ }
51
+ });
52
+ const sender = {
53
+ addonKey: sanitisedExtension.addon_key,
54
+ key: sanitisedExtension.key,
55
+ options: sanitisedExtension.options
56
+ };
57
+ eventActions.broadcastPublic(type, event, unsanitisedExtension);
58
+ expect(spy).toHaveBeenCalledWith({
59
+ event,
60
+ extension: unsanitisedExtension,
61
+ type
62
+ });
63
+ expect(simpleXDM.dispatch).toHaveBeenCalledWith(type, {}, {
64
+ event,
65
+ sender
66
+ });
67
+ HostApi.offPublicEventDispatched(spy);
68
+ });
69
+
70
+ it('offEventDispatched unbinds', function(){
71
+ var spy = jasmine.createSpy('anotherspy');
72
+ HostApi.onPublicEventDispatched(spy);
73
+ HostApi.offPublicEventDispatched(spy);
74
+ eventActions.broadcastPublic('a', {}, {
75
+ addon_key: 'abc',
76
+ key: '123'
77
+ });
78
+ expect(spy).not.toHaveBeenCalled();
79
+ });
80
+
81
+ it('setJwtClockSkew sets the clockSkew', function(done){
82
+ var skew = 12345;
83
+ EventDispatcher.once('jwt-skew-set', (data) => {
84
+ expect(data.skew).toEqual(skew);
85
+ done();
86
+ });
87
+ HostApi.setJwtClockSkew(skew);
88
+ });
89
+
90
+ it('getContentResolver gets the content resolver', function(){
91
+ var testContentResolver = function(params){};
92
+ HostApi.registerContentResolver.resolveByExtension(testContentResolver);
93
+ expect(HostApi.getContentResolver()).toEqual(testContentResolver);
94
+ });
95
+
96
+ it('dialog.create uses dialog module options', function(done){
97
+ var extension = {
98
+ addon_key: 'abc',
99
+ key: 'abc123'
100
+ };
101
+ var dialogOptions = {
102
+ height: '200px',
103
+ title: 'overriden'
104
+ };
105
+ var dialogBeanOptions = {
106
+ width: '123px',
107
+ title: 'override me'
108
+ };
109
+ // mock dialogBean options being placed in the product
110
+ window._AP = {
111
+ dialogModules: {
112
+ abc: {
113
+ abc123: {
114
+ options: dialogBeanOptions
115
+ }
116
+ }
117
+ }
118
+ };
119
+
120
+ EventDispatcher.registerOnce('after:dialog-extension-open', (e) => {
121
+ expect(e.extension).toEqual({
122
+ addon_key: extension.addon_key,
123
+ key: extension.key
124
+ });
125
+ expect(e.options).toEqual({
126
+ height: dialogOptions.height,
127
+ width: dialogBeanOptions.width,
128
+ title: dialogOptions.title
129
+ });
130
+ done();
131
+ });
132
+
133
+ HostApi.dialog.create(extension, dialogOptions);
134
+ });
135
+
136
+ it('Registered click handler gets called with reference to iframe', () => {
137
+ const target_spec = {
138
+ addon_key: 'some-key',
139
+ key: 'module-key'
140
+ };
141
+ const reg = {
142
+ extension: target_spec,
143
+ extension_id: `${target_spec.addon_key}__${target_spec.key}`
144
+ };
145
+ const iframe = document.createElement('iframe');
146
+ const callback = jasmine.createSpy('callback');
147
+
148
+ iframe.id = reg.extension_id;
149
+ document.body.appendChild(iframe);
150
+ HostApi.onFrameClick(callback);
151
+ simpleXDM._xdm._handleAddonClick(null, reg);
152
+ expect(callback).toHaveBeenCalled();
153
+ expect(callback.calls.mostRecent().args[0]).toEqual(iframe);
154
+ document.body.removeChild(iframe);
155
+ });
156
+
157
+ it('destroy removes the extension', () => {
158
+ const spec = {
159
+ addon_key: 'my-addon-key',
160
+ key: 'somekey',
161
+ url: 'http://www.example.com'
162
+ };
163
+ let iframe = HostApi.create(spec);
164
+ let extensions = HostApi.getExtensions(spec);
165
+ expect(extensions.length).toEqual(1);
166
+ HostApi.destroy(extensions[0].extension_id);
167
+ expect(HostApi.getExtensions(spec).length).toEqual(0);
168
+ });
169
+
170
+ it('closes a dialog using the provider', () => {
171
+ const spec = {
172
+ addon_key: 'abc123-addon-key',
173
+ key: 'some-key',
174
+ url: 'http://www.example.com'
175
+ };
176
+ const closeSpy = jasmine.createSpy('spy');
177
+ const frameworkAdaptor = {
178
+ getProviderByModuleName: function(){
179
+ return {
180
+ close: closeSpy,
181
+ isActiveDialog: jasmine.createSpy('spy').and.returnValue(true)
182
+ };
183
+ }
184
+ };
185
+ HostApi.setFrameworkAdaptor(frameworkAdaptor);
186
+ HostApi.dialog.close(spec.addon_key);
187
+ expect(closeSpy).toHaveBeenCalled();
188
+ });
189
+
190
+ it('can tell if module is defined', () => {
191
+ const moduleName = 'foo';
192
+ simpleXDM.defineModule(moduleName, {});
193
+ expect(HostApi.isModuleDefined(moduleName)).toBe(true);
194
+ });
195
+
196
+ it('onIframeTimeout binds', function() {
197
+ var spy = jasmine.createSpy('spy');
198
+ HostApi.onIframeTimeout(spy);
199
+ EventDispatcher.dispatch('after:iframe-bridge-timeout', {extension:{options:{}}});
200
+ expect(spy).toHaveBeenCalled();
201
+ });
202
+
203
+ it('onIframePerformanceTelemetry binds', function() {
204
+ var spy = jasmine.createSpy('spy');
205
+ HostApi.onIframePerformanceTelemetry(spy);
206
+ EventDispatcher.dispatch('after:analytics-iframe-performance', {extension:{options:{}}, metrics: {}});
207
+ expect(spy).toHaveBeenCalled();
208
+ });
209
+
210
+ it('onIframeVisible binds', function() {
211
+ var spy = jasmine.createSpy('spy');
212
+ HostApi.onIframeVisible(spy);
213
+ EventDispatcher.dispatch('iframe-visible', {options:{}});
214
+ expect(spy).toHaveBeenCalled();
215
+ });
216
+
217
+ it('exports targetSpecNoDialogs', function() {
218
+ expect(typeof HostApi.targetSpecNoDialogs).toBe('function');
219
+ });
220
+ });
@@ -0,0 +1,43 @@
1
+ import IframeCreate from 'src/host/iframe-create';
2
+
3
+ describe('Iframe Create', () => {
4
+ var extensionConfig = {
5
+ addon_key: 'addon-key',
6
+ key: 'module-key',
7
+ url: '/iframe-content.html',
8
+ options: {
9
+ isGeneral: true
10
+ }, //options to send to the iframe
11
+ data: { //data to stay on the host side
12
+ pageType: 'general',
13
+ productCtx: '{}',
14
+ uid: 'someUserId'
15
+ }
16
+ };
17
+
18
+
19
+ it('returns an iframe container node', () => {
20
+ var container = IframeCreate(extensionConfig);
21
+ expect(container.length).toEqual(1);
22
+ expect(container.hasClass('ap-iframe-container')).toBe(true);
23
+ expect(container.find('iframe').length).toEqual(1);
24
+ });
25
+
26
+ describe('iframe has attribute', () => {
27
+ var iframe = IframeCreate(extensionConfig).find('iframe');
28
+ it('src', () => {
29
+ expect(iframe.attr('src')).toContain(extensionConfig.url);
30
+ });
31
+
32
+ it('id', () => {
33
+ expect(iframe.attr('id')).toContain(extensionConfig.addon_key);
34
+ expect(iframe.attr('id')).toContain(extensionConfig.key);
35
+ });
36
+
37
+ it('name', () => {
38
+ expect(iframe.attr('name')).toContain('{}');
39
+ });
40
+
41
+ });
42
+
43
+ });
@@ -0,0 +1,19 @@
1
+ import IframeContainerComponent from 'src/host/components/iframe_container';
2
+
3
+ describe('Iframe container component', () => {
4
+
5
+ describe('createExtension', () => {
6
+
7
+ it('returns a container', () => {
8
+ var extension = {
9
+ addon_key: 'some-addon-key',
10
+ key: 'some-module-key',
11
+ url: 'https://www.example.com'
12
+ };
13
+ var createdExtension = IframeContainerComponent.createExtension(extension);
14
+ expect(createdExtension.hasClass('ap-iframe-container')).toBe(true);
15
+ });
16
+ });
17
+
18
+
19
+ });