@raydiant/playlist-window-manager 0.20.0 → 0.21.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.
@@ -0,0 +1,221 @@
1
+ import {
2
+ createPresentationWindow,
3
+ createPresentation,
4
+ createApplicationVersion,
5
+ createRenderer,
6
+ createPlaylistWindowManagerState,
7
+ createRuleEngineState,
8
+ } from './testUtils';
9
+
10
+ const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
11
+
12
+ describe('embedded apps', () => {
13
+ test('loads embedded url format', async () => {
14
+ const testRenderer = createRenderer();
15
+
16
+ const window = createPresentationWindow({
17
+ windowId: 'test-embedded-url-format',
18
+ presentation: createPresentation({
19
+ applicationVariables: { input: 'test' },
20
+ }),
21
+ applicationVersion: createApplicationVersion({
22
+ embeddedUrlFormat: 'http://test.local/:input',
23
+ presentationProperties: [{ name: 'input', type: 'string' }],
24
+ }),
25
+ renderer: testRenderer,
26
+ });
27
+
28
+ await window.load();
29
+
30
+ expect(testRenderer.createWindow).toHaveBeenCalledWith({
31
+ windowId: 'test-embedded-url-format',
32
+ backgroundColor: '#ffffff',
33
+ bounds: undefined,
34
+ parentWindowId: undefined,
35
+ errorCallback: expect.any(Function),
36
+ receiveMessageCallback: expect.any(Function),
37
+ });
38
+
39
+ expect(testRenderer.loadWindow).toHaveBeenCalledWith(
40
+ 'test-embedded-url-format',
41
+ 'http://test.local/test#__raydiantWindowId=test-embedded-url-format'
42
+ );
43
+ });
44
+
45
+ test('reloads by rendering embedded url format', async () => {
46
+ const testRenderer = createRenderer();
47
+
48
+ const window = createPresentationWindow({
49
+ windowId: 'test-reload-url',
50
+ presentation: createPresentation({
51
+ applicationVariables: { input: 'test' },
52
+ }),
53
+ applicationVersion: createApplicationVersion({
54
+ embeddedUrlFormat: 'http://test.local/:input',
55
+ presentationProperties: [{ name: 'input', type: 'string' }],
56
+ }),
57
+ renderer: testRenderer,
58
+ });
59
+
60
+ await window.load();
61
+
62
+ window.setPresentation(
63
+ createPresentation({ applicationVariables: { input: 'updated' } }),
64
+ createPlaylistWindowManagerState(),
65
+ createRuleEngineState()
66
+ );
67
+
68
+ await window.reload();
69
+
70
+ expect(testRenderer.loadWindow).toHaveBeenCalledTimes(2);
71
+
72
+ expect(testRenderer.loadWindow).toHaveBeenCalledWith(
73
+ 'test-reload-url',
74
+ 'http://test.local/updated#__raydiantWindowId=test-reload-url'
75
+ );
76
+ });
77
+
78
+ test('reloads by sending message if has preview subscription', async () => {
79
+ const testRenderer = createRenderer();
80
+
81
+ const window = createPresentationWindow({
82
+ windowId: 'test-reload-message',
83
+ presentation: createPresentation({
84
+ applicationVariables: { input: 'test' },
85
+ }),
86
+ applicationVersion: createApplicationVersion({
87
+ embeddedUrlFormat: 'http://test.local/:input',
88
+ presentationProperties: [{ name: 'input', type: 'string' }],
89
+ }),
90
+ renderer: testRenderer,
91
+ });
92
+
93
+ await window.load();
94
+
95
+ // Subscribe to receive input updates via message.
96
+ testRenderer.runReceiveMessageCallback('preview-subscribe', 'inputs');
97
+
98
+ window.setPresentation(
99
+ createPresentation({ applicationVariables: { input: 'updated' } }),
100
+ createPlaylistWindowManagerState(),
101
+ createRuleEngineState()
102
+ );
103
+
104
+ await window.reload();
105
+
106
+ // loadWindow should only be called once for the initial load.
107
+ expect(testRenderer.loadWindow).toHaveBeenCalledTimes(1);
108
+
109
+ expect(testRenderer.sendMessageObject).toHaveBeenCalledWith(
110
+ 'test-reload-message',
111
+ 'preview-inputs',
112
+ { input: 'updated' }
113
+ );
114
+
115
+ // sendMessageObject should not be called again for the same inputs.
116
+ await window.reload();
117
+ expect(testRenderer.sendMessageObject).toHaveBeenCalledTimes(1);
118
+
119
+ // Unsubscribe to receive input updates via message.
120
+ testRenderer.runReceiveMessageCallback('preview-unsubscribe', 'inputs');
121
+
122
+ await window.reload();
123
+ // loadWindow should be called again since the preview subscription was removed.
124
+ expect(testRenderer.loadWindow).toHaveBeenCalledTimes(2);
125
+ });
126
+
127
+ test('preview subscription strips internal file properties from inputs', async () => {
128
+ const testRenderer = createRenderer();
129
+
130
+ const window = createPresentationWindow({
131
+ windowId: 'test-reload-message',
132
+ presentation: createPresentation({
133
+ applicationVariables: {
134
+ input: {
135
+ url: 'http://test.local/image.png',
136
+ 'content-length': 123,
137
+ 'content-type': 'image/png',
138
+ file_upload_id: 'test',
139
+ filename: 'image.png',
140
+ },
141
+ },
142
+ }),
143
+ applicationVersion: createApplicationVersion({
144
+ embeddedUrlFormat: 'http://test.local/:input',
145
+ presentationProperties: [{ name: 'input', type: 'file' }],
146
+ }),
147
+ renderer: testRenderer,
148
+ });
149
+
150
+ await window.load();
151
+
152
+ // Subscribe to receive input updates via message.
153
+ testRenderer.runReceiveMessageCallback('preview-subscribe', 'inputs');
154
+
155
+ await window.reload();
156
+
157
+ expect(testRenderer.sendMessageObject).toHaveBeenCalledWith(
158
+ 'test-reload-message',
159
+ 'preview-inputs',
160
+ { input: { url: 'http://test.local/image.png' } }
161
+ );
162
+
163
+ // Updating internal file input values should not cause a reload.
164
+ window.setPresentation(
165
+ createPresentation({
166
+ applicationVariables: {
167
+ input: {
168
+ url: 'http://test.local/image.png',
169
+ file_upload_id: 'test2',
170
+ },
171
+ },
172
+ }),
173
+ createPlaylistWindowManagerState(),
174
+ createRuleEngineState()
175
+ );
176
+
177
+ await window.reload();
178
+
179
+ // sendMessageObject should not be called again for the same inputs.
180
+ expect(testRenderer.sendMessageObject).toHaveBeenCalledTimes(1);
181
+ });
182
+
183
+ test('sends create object url message', async () => {
184
+ const testRenderer = createRenderer();
185
+
186
+ const window = createPresentationWindow({
187
+ windowId: 'test-object-url',
188
+ presentation: createPresentation(),
189
+ applicationVersion: createApplicationVersion({
190
+ embeddedUrlFormat: 'http://test.local/:input',
191
+ }),
192
+ renderer: testRenderer,
193
+ });
194
+
195
+ await window.load();
196
+
197
+ const createObjectUrlPromise = window.createObjectURL(new Blob(['test']));
198
+
199
+ // Wait for the createObjectURL call to be sent to the renderer.
200
+ await delay(100);
201
+
202
+ expect(testRenderer.sendMessageObject).toHaveBeenCalledWith(
203
+ 'test-object-url',
204
+ 'create-object-url',
205
+ { requestId: expect.any(String), buffer: expect.any(ArrayBuffer) }
206
+ );
207
+
208
+ // Extract the requestId from the call to the renderer.
209
+ const { requestId } = testRenderer.sendMessageObject.mock.calls[0][2];
210
+
211
+ testRenderer.runReceiveMessageCallback('create-object-url-result', {
212
+ requestId,
213
+ url: 'http://test.local/blob',
214
+ });
215
+
216
+ const result = await createObjectUrlPromise;
217
+ expect(result).toBe('http://test.local/blob');
218
+ });
219
+ });
220
+
221
+ // TODO: Backfill tests for all legacy and embedded apps.