request-iframe 0.0.5 → 0.0.6
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.
- package/README.CN.md +1 -1
- package/README.md +1 -1
- package/package.json +5 -4
- package/react/library/index.d.ts.map +1 -1
- package/react/library/index.js +4 -1
- package/library/__tests__/channel.test.ts +0 -432
- package/library/__tests__/coverage-branches.test.ts +0 -356
- package/library/__tests__/debug.test.ts +0 -610
- package/library/__tests__/dispatcher.test.ts +0 -485
- package/library/__tests__/interceptors.test.ts +0 -146
- package/library/__tests__/requestIframe.test.ts +0 -5590
- package/library/__tests__/server.test.ts +0 -738
- package/library/__tests__/stream.test.ts +0 -726
- package/library/__tests__/utils.test.ts +0 -473
- package/library/api/client.d.js +0 -5
- package/library/api/server.d.js +0 -5
- package/library/constants/index.d.js +0 -36
- package/library/constants/messages.d.js +0 -5
- package/library/core/client.d.js +0 -5
- package/library/core/message-handler.d.ts +0 -110
- package/library/core/message-handler.d.ts.map +0 -1
- package/library/core/message-handler.js +0 -320
- package/library/core/request-response.d.ts +0 -59
- package/library/core/request-response.d.ts.map +0 -1
- package/library/core/request-response.js +0 -337
- package/library/core/request.d.js +0 -5
- package/library/core/response.d.js +0 -5
- package/library/core/server-base.d.ts +0 -86
- package/library/core/server-base.d.ts.map +0 -1
- package/library/core/server-base.js +0 -257
- package/library/core/server-client.d.js +0 -5
- package/library/core/server-client.d.ts +0 -101
- package/library/core/server-client.d.ts.map +0 -1
- package/library/core/server-client.js +0 -266
- package/library/core/server.d.js +0 -5
- package/library/interceptors/index.d.js +0 -5
- package/library/message/channel.d.js +0 -5
- package/library/message/dispatcher.d.js +0 -5
- package/library/message/index.d.js +0 -25
- package/library/stream/file-stream.d.js +0 -4
- package/library/stream/index.d.js +0 -58
- package/library/stream/readable-stream.d.js +0 -5
- package/library/stream/types.d.js +0 -5
- package/library/stream/writable-stream.d.js +0 -5
- package/library/types/index.d.js +0 -5
- package/library/utils/cache.d.js +0 -5
- package/library/utils/cookie.d.js +0 -5
- package/library/utils/debug.d.js +0 -5
- package/library/utils/index.d.js +0 -94
- package/library/utils/path-match.d.js +0 -5
- package/library/utils/protocol.d.js +0 -5
- package/react/library/__tests__/index.test.d.ts +0 -2
- package/react/library/__tests__/index.test.d.ts.map +0 -1
- package/react/library/__tests__/index.test.tsx +0 -792
package/README.CN.md
CHANGED
|
@@ -274,7 +274,7 @@ await client.send('/config', {
|
|
|
274
274
|
});
|
|
275
275
|
|
|
276
276
|
// 监听组件事件(通过反向通信)
|
|
277
|
-
const server = requestIframeServer({ secretKey: 'widget
|
|
277
|
+
const server = requestIframeServer({ secretKey: 'widget' });
|
|
278
278
|
server.on('/event', (req, res) => {
|
|
279
279
|
console.log('组件事件:', req.body);
|
|
280
280
|
res.send({ received: true });
|
package/README.md
CHANGED
|
@@ -165,7 +165,7 @@ await client.send('/config', {
|
|
|
165
165
|
});
|
|
166
166
|
|
|
167
167
|
// Listen to component events (via reverse communication)
|
|
168
|
-
const server = requestIframeServer({ secretKey: 'widget
|
|
168
|
+
const server = requestIframeServer({ secretKey: 'widget' });
|
|
169
169
|
server.on('/event', (req, res) => {
|
|
170
170
|
console.log('Component event:', req.body);
|
|
171
171
|
res.send({ received: true });
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "request-iframe",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Communicate with iframes like sending HTTP requests",
|
|
5
5
|
"main": "library/index.js",
|
|
6
6
|
"types": "library/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "npm run build:types && npm run build:js && npm run build-react:types && npm run build-react:js",
|
|
8
|
+
"build": "npm run build:types && npm run build:js && npm run build-react:types && npm run build-react:js && npm run build:clean",
|
|
9
9
|
"build:types": "tsc --emitDeclarationOnly",
|
|
10
|
-
"build:js": "babel src --out-dir library --extensions .ts --copy-files",
|
|
10
|
+
"build:js": "babel src --out-dir library --extensions .ts --copy-files --ignore \"**/__tests__/**\",\"**/*.test.ts\"",
|
|
11
11
|
"build-react:types": "tsc -p react/tsconfig.json --emitDeclarationOnly",
|
|
12
|
-
"build-react:js": "babel react/src --out-dir react/library --extensions .ts --copy-files",
|
|
12
|
+
"build-react:js": "babel react/src --out-dir react/library --extensions .ts,.tsx --copy-files --ignore \"**/__tests__/**\",\"**/*.test.ts\",\"**/*.test.tsx\"",
|
|
13
|
+
"build:clean": "node scripts/clean-build.js",
|
|
13
14
|
"test": "jest",
|
|
14
15
|
"test:watch": "jest --watch",
|
|
15
16
|
"test:coverage": "jest --coverage",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1F,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAEf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,SAAS,CACvB,aAAa,EAAE,CAAC,MAAM,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAAC,EACvG,OAAO,CAAC,EAAE,0BAA0B,EACpC,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,GACxB,mBAAmB,GAAG,IAAI,CA2E5B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,SAAS,CACvB,OAAO,CAAC,EAAE,0BAA0B,EACpC,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,GACxB,mBAAmB,GAAG,IAAI,CA2C5B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,IAAI,CAmBN;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EAClC,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1F,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAEf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,SAAS,CACvB,aAAa,EAAE,CAAC,MAAM,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAAC,EACvG,OAAO,CAAC,EAAE,0BAA0B,EACpC,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,GACxB,mBAAmB,GAAG,IAAI,CA2E5B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,SAAS,CACvB,OAAO,CAAC,EAAE,0BAA0B,EACpC,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,GACxB,mBAAmB,GAAG,IAAI,CA2C5B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,IAAI,CAmBN;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EAClC,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,IAAI,CA+BN"}
|
package/react/library/index.js
CHANGED
|
@@ -268,6 +268,9 @@ function useServerHandlerMap(server, map, deps) {
|
|
|
268
268
|
var keys = (0, _react.useMemo)(() => {
|
|
269
269
|
return Object.keys(map).sort();
|
|
270
270
|
}, [map]);
|
|
271
|
+
var keysStr = (0, _react.useMemo)(() => {
|
|
272
|
+
return keys.join(',');
|
|
273
|
+
}, [keys]);
|
|
271
274
|
var mapWrapper = (0, _react.useMemo)(() => {
|
|
272
275
|
return keys.reduce((acc, key) => {
|
|
273
276
|
acc[key] = function (req, res) {
|
|
@@ -276,7 +279,7 @@ function useServerHandlerMap(server, map, deps) {
|
|
|
276
279
|
};
|
|
277
280
|
return acc;
|
|
278
281
|
}, {});
|
|
279
|
-
}, [
|
|
282
|
+
}, [keysStr]);
|
|
280
283
|
(0, _react.useEffect)(() => {
|
|
281
284
|
if (!server) {
|
|
282
285
|
return;
|
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
import { MessageChannel, ChannelType, MessageContext } from '../message/channel';
|
|
2
|
-
import { createPostMessage } from '../utils';
|
|
3
|
-
import { MessageType, MessageRole } from '../constants';
|
|
4
|
-
|
|
5
|
-
describe('MessageChannel', () => {
|
|
6
|
-
let channel: MessageChannel;
|
|
7
|
-
let mockReceiver: jest.Mock;
|
|
8
|
-
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
mockReceiver = jest.fn();
|
|
11
|
-
channel = new MessageChannel();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
afterEach(() => {
|
|
15
|
-
channel.destroy();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
describe('constructor', () => {
|
|
19
|
-
it('should create channel with default type', () => {
|
|
20
|
-
expect(channel.type).toBe(ChannelType.POST_MESSAGE);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should create channel with secretKey', () => {
|
|
24
|
-
const channelWithKey = new MessageChannel('test-key');
|
|
25
|
-
expect(channelWithKey.secretKey).toBe('test-key');
|
|
26
|
-
channelWithKey.destroy();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should add message event listener', () => {
|
|
30
|
-
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
|
|
31
|
-
const testChannel = new MessageChannel();
|
|
32
|
-
expect(addEventListenerSpy).toHaveBeenCalledWith('message', expect.any(Function));
|
|
33
|
-
testChannel.destroy();
|
|
34
|
-
addEventListenerSpy.mockRestore();
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe('addReceiver and removeReceiver', () => {
|
|
39
|
-
it('should add receiver callback', () => {
|
|
40
|
-
channel.addReceiver(mockReceiver);
|
|
41
|
-
|
|
42
|
-
const message = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
43
|
-
path: 'test'
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
window.dispatchEvent(
|
|
47
|
-
new MessageEvent('message', {
|
|
48
|
-
data: message,
|
|
49
|
-
origin: 'https://example.com'
|
|
50
|
-
})
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
// Wait for async message handling
|
|
54
|
-
setTimeout(() => {
|
|
55
|
-
expect(mockReceiver).toHaveBeenCalled();
|
|
56
|
-
}, 10);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('should remove receiver callback', () => {
|
|
60
|
-
channel.addReceiver(mockReceiver);
|
|
61
|
-
channel.removeReceiver(mockReceiver);
|
|
62
|
-
|
|
63
|
-
const message = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
64
|
-
path: 'test'
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
window.dispatchEvent(
|
|
68
|
-
new MessageEvent('message', {
|
|
69
|
-
data: message,
|
|
70
|
-
origin: 'https://example.com'
|
|
71
|
-
})
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
// Wait for async message handling
|
|
75
|
-
setTimeout(() => {
|
|
76
|
-
expect(mockReceiver).not.toHaveBeenCalled();
|
|
77
|
-
}, 10);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should support multiple receivers', () => {
|
|
81
|
-
const receiver1 = jest.fn();
|
|
82
|
-
const receiver2 = jest.fn();
|
|
83
|
-
|
|
84
|
-
channel.addReceiver(receiver1);
|
|
85
|
-
channel.addReceiver(receiver2);
|
|
86
|
-
|
|
87
|
-
const message = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
88
|
-
path: 'test'
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
window.dispatchEvent(
|
|
92
|
-
new MessageEvent('message', {
|
|
93
|
-
data: message,
|
|
94
|
-
origin: 'https://example.com'
|
|
95
|
-
})
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
// Wait for async message handling
|
|
99
|
-
setTimeout(() => {
|
|
100
|
-
expect(receiver1).toHaveBeenCalled();
|
|
101
|
-
expect(receiver2).toHaveBeenCalled();
|
|
102
|
-
}, 10);
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
describe('reference counting', () => {
|
|
107
|
-
it('should increment reference count', () => {
|
|
108
|
-
expect(channel.getRefCount()).toBe(0);
|
|
109
|
-
channel.addRef();
|
|
110
|
-
expect(channel.getRefCount()).toBe(1);
|
|
111
|
-
channel.addRef();
|
|
112
|
-
expect(channel.getRefCount()).toBe(2);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it('should decrement reference count', () => {
|
|
116
|
-
channel.addRef();
|
|
117
|
-
channel.addRef();
|
|
118
|
-
expect(channel.release()).toBe(1);
|
|
119
|
-
expect(channel.release()).toBe(0);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
describe('message filtering', () => {
|
|
124
|
-
it('should filter messages by secretKey', () => {
|
|
125
|
-
const channelWithKey = new MessageChannel('test-key');
|
|
126
|
-
channelWithKey.addReceiver(mockReceiver);
|
|
127
|
-
|
|
128
|
-
// Message with matching secretKey
|
|
129
|
-
const validMessage = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
130
|
-
path: 'test',
|
|
131
|
-
secretKey: 'test-key'
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
window.dispatchEvent(
|
|
135
|
-
new MessageEvent('message', {
|
|
136
|
-
data: validMessage,
|
|
137
|
-
origin: 'https://example.com'
|
|
138
|
-
})
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
// Message with different secretKey
|
|
142
|
-
const invalidMessage = createPostMessage(MessageType.REQUEST, 'req124', {
|
|
143
|
-
path: 'test',
|
|
144
|
-
secretKey: 'other-key'
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
window.dispatchEvent(
|
|
148
|
-
new MessageEvent('message', {
|
|
149
|
-
data: invalidMessage,
|
|
150
|
-
origin: 'https://example.com'
|
|
151
|
-
})
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
setTimeout(() => {
|
|
155
|
-
expect(mockReceiver).toHaveBeenCalledTimes(1);
|
|
156
|
-
expect(mockReceiver).toHaveBeenCalledWith(
|
|
157
|
-
validMessage,
|
|
158
|
-
expect.objectContaining({
|
|
159
|
-
origin: 'https://example.com'
|
|
160
|
-
})
|
|
161
|
-
);
|
|
162
|
-
}, 10);
|
|
163
|
-
|
|
164
|
-
channelWithKey.destroy();
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('should filter messages without secretKey when channel has secretKey', () => {
|
|
168
|
-
const channelWithKey = new MessageChannel('test-key');
|
|
169
|
-
channelWithKey.addReceiver(mockReceiver);
|
|
170
|
-
|
|
171
|
-
// Message without secretKey
|
|
172
|
-
const message = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
173
|
-
path: 'test'
|
|
174
|
-
});
|
|
175
|
-
delete (message as any).secretKey;
|
|
176
|
-
|
|
177
|
-
window.dispatchEvent(
|
|
178
|
-
new MessageEvent('message', {
|
|
179
|
-
data: message,
|
|
180
|
-
origin: 'https://example.com'
|
|
181
|
-
})
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
setTimeout(() => {
|
|
185
|
-
expect(mockReceiver).not.toHaveBeenCalled();
|
|
186
|
-
}, 10);
|
|
187
|
-
|
|
188
|
-
channelWithKey.destroy();
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it('should accept messages without secretKey when channel has no secretKey', () => {
|
|
192
|
-
channel.addReceiver(mockReceiver);
|
|
193
|
-
|
|
194
|
-
const message = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
195
|
-
path: 'test'
|
|
196
|
-
});
|
|
197
|
-
delete (message as any).secretKey;
|
|
198
|
-
|
|
199
|
-
window.dispatchEvent(
|
|
200
|
-
new MessageEvent('message', {
|
|
201
|
-
data: message,
|
|
202
|
-
origin: 'https://example.com'
|
|
203
|
-
})
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
setTimeout(() => {
|
|
207
|
-
expect(mockReceiver).toHaveBeenCalled();
|
|
208
|
-
}, 10);
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it('should ignore invalid postMessage format', () => {
|
|
212
|
-
channel.addReceiver(mockReceiver);
|
|
213
|
-
|
|
214
|
-
window.dispatchEvent(
|
|
215
|
-
new MessageEvent('message', {
|
|
216
|
-
data: { invalid: 'message' },
|
|
217
|
-
origin: 'https://example.com'
|
|
218
|
-
})
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
setTimeout(() => {
|
|
222
|
-
expect(mockReceiver).not.toHaveBeenCalled();
|
|
223
|
-
}, 10);
|
|
224
|
-
});
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
describe('send', () => {
|
|
228
|
-
it('should send message to target window', () => {
|
|
229
|
-
const targetWindow = {
|
|
230
|
-
closed: false,
|
|
231
|
-
document: {},
|
|
232
|
-
postMessage: jest.fn()
|
|
233
|
-
} as any;
|
|
234
|
-
|
|
235
|
-
const message = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
236
|
-
path: 'test'
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
const ok = channel.send(targetWindow, message, 'https://example.com');
|
|
240
|
-
|
|
241
|
-
expect(ok).toBe(true);
|
|
242
|
-
expect(targetWindow.postMessage).toHaveBeenCalledWith(
|
|
243
|
-
message,
|
|
244
|
-
'https://example.com'
|
|
245
|
-
);
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it('should use default origin * when not specified', () => {
|
|
249
|
-
const targetWindow = {
|
|
250
|
-
closed: false,
|
|
251
|
-
document: {},
|
|
252
|
-
postMessage: jest.fn()
|
|
253
|
-
} as any;
|
|
254
|
-
|
|
255
|
-
const message = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
256
|
-
path: 'test'
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
const ok = channel.send(targetWindow, message);
|
|
260
|
-
|
|
261
|
-
expect(ok).toBe(true);
|
|
262
|
-
expect(targetWindow.postMessage).toHaveBeenCalledWith(
|
|
263
|
-
message,
|
|
264
|
-
'*'
|
|
265
|
-
);
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
describe('sendMessage', () => {
|
|
270
|
-
it('should create and send message', () => {
|
|
271
|
-
const targetWindow = {
|
|
272
|
-
closed: false,
|
|
273
|
-
document: {},
|
|
274
|
-
postMessage: jest.fn()
|
|
275
|
-
} as any;
|
|
276
|
-
|
|
277
|
-
const ok = channel.sendMessage(
|
|
278
|
-
targetWindow,
|
|
279
|
-
'https://example.com',
|
|
280
|
-
MessageType.REQUEST,
|
|
281
|
-
'req123',
|
|
282
|
-
{
|
|
283
|
-
path: 'test',
|
|
284
|
-
body: { param: 'value' }
|
|
285
|
-
}
|
|
286
|
-
);
|
|
287
|
-
|
|
288
|
-
expect(ok).toBe(true);
|
|
289
|
-
expect(targetWindow.postMessage).toHaveBeenCalledWith(
|
|
290
|
-
expect.objectContaining({
|
|
291
|
-
__requestIframe__: 1,
|
|
292
|
-
type: 'request',
|
|
293
|
-
requestId: 'req123',
|
|
294
|
-
path: 'test',
|
|
295
|
-
body: { param: 'value' },
|
|
296
|
-
secretKey: undefined
|
|
297
|
-
}),
|
|
298
|
-
'https://example.com'
|
|
299
|
-
);
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
it('should include secretKey in message', () => {
|
|
303
|
-
const channelWithKey = new MessageChannel('test-key');
|
|
304
|
-
const targetWindow = {
|
|
305
|
-
closed: false,
|
|
306
|
-
document: {},
|
|
307
|
-
postMessage: jest.fn()
|
|
308
|
-
} as any;
|
|
309
|
-
|
|
310
|
-
const ok = channelWithKey.sendMessage(
|
|
311
|
-
targetWindow,
|
|
312
|
-
'https://example.com',
|
|
313
|
-
MessageType.REQUEST,
|
|
314
|
-
'req123',
|
|
315
|
-
{ path: 'test' }
|
|
316
|
-
);
|
|
317
|
-
|
|
318
|
-
expect(ok).toBe(true);
|
|
319
|
-
expect(targetWindow.postMessage).toHaveBeenCalledWith(
|
|
320
|
-
expect.objectContaining({
|
|
321
|
-
secretKey: 'test-key'
|
|
322
|
-
}),
|
|
323
|
-
'https://example.com'
|
|
324
|
-
);
|
|
325
|
-
|
|
326
|
-
channelWithKey.destroy();
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
describe('prefixPath', () => {
|
|
331
|
-
it('should add secretKey prefix when secretKey exists', () => {
|
|
332
|
-
const channelWithKey = new MessageChannel('test-key');
|
|
333
|
-
expect(channelWithKey.prefixPath('test')).toBe('test-key:test');
|
|
334
|
-
channelWithKey.destroy();
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
it('should return path as-is when no secretKey', () => {
|
|
338
|
-
expect(channel.prefixPath('test')).toBe('test');
|
|
339
|
-
});
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
describe('extractContext', () => {
|
|
343
|
-
it('should extract context from MessageEvent', () => {
|
|
344
|
-
channel.addReceiver(mockReceiver);
|
|
345
|
-
|
|
346
|
-
const sourceWindow = window;
|
|
347
|
-
const message = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
348
|
-
path: 'test'
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
window.dispatchEvent(
|
|
352
|
-
new MessageEvent('message', {
|
|
353
|
-
data: message,
|
|
354
|
-
origin: 'https://example.com',
|
|
355
|
-
source: sourceWindow
|
|
356
|
-
})
|
|
357
|
-
);
|
|
358
|
-
|
|
359
|
-
setTimeout(() => {
|
|
360
|
-
expect(mockReceiver).toHaveBeenCalledWith(
|
|
361
|
-
message,
|
|
362
|
-
expect.objectContaining({
|
|
363
|
-
source: sourceWindow,
|
|
364
|
-
origin: 'https://example.com'
|
|
365
|
-
})
|
|
366
|
-
);
|
|
367
|
-
}, 10);
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
describe('error handling', () => {
|
|
372
|
-
it('should handle receiver errors gracefully', () => {
|
|
373
|
-
const errorReceiver = jest.fn(() => {
|
|
374
|
-
throw new Error('Receiver error');
|
|
375
|
-
});
|
|
376
|
-
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
377
|
-
|
|
378
|
-
channel.addReceiver(errorReceiver);
|
|
379
|
-
channel.addReceiver(mockReceiver);
|
|
380
|
-
|
|
381
|
-
const message = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
382
|
-
path: 'test'
|
|
383
|
-
});
|
|
384
|
-
|
|
385
|
-
window.dispatchEvent(
|
|
386
|
-
new MessageEvent('message', {
|
|
387
|
-
data: message,
|
|
388
|
-
origin: 'https://example.com'
|
|
389
|
-
})
|
|
390
|
-
);
|
|
391
|
-
|
|
392
|
-
setTimeout(() => {
|
|
393
|
-
expect(errorReceiver).toHaveBeenCalled();
|
|
394
|
-
expect(mockReceiver).toHaveBeenCalled(); // Other receivers should still be called
|
|
395
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
396
|
-
'[request-iframe] Receiver error:',
|
|
397
|
-
expect.any(Error)
|
|
398
|
-
);
|
|
399
|
-
consoleErrorSpy.mockRestore();
|
|
400
|
-
}, 10);
|
|
401
|
-
});
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
describe('destroy', () => {
|
|
405
|
-
it('should remove event listener', () => {
|
|
406
|
-
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
|
|
407
|
-
channel.destroy();
|
|
408
|
-
expect(removeEventListenerSpy).toHaveBeenCalledWith('message', expect.any(Function));
|
|
409
|
-
removeEventListenerSpy.mockRestore();
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
it('should clear receivers', () => {
|
|
413
|
-
channel.addReceiver(mockReceiver);
|
|
414
|
-
channel.destroy();
|
|
415
|
-
|
|
416
|
-
const message = createPostMessage(MessageType.REQUEST, 'req123', {
|
|
417
|
-
path: 'test'
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
window.dispatchEvent(
|
|
421
|
-
new MessageEvent('message', {
|
|
422
|
-
data: message,
|
|
423
|
-
origin: 'https://example.com'
|
|
424
|
-
})
|
|
425
|
-
);
|
|
426
|
-
|
|
427
|
-
setTimeout(() => {
|
|
428
|
-
expect(mockReceiver).not.toHaveBeenCalled();
|
|
429
|
-
}, 10);
|
|
430
|
-
});
|
|
431
|
-
});
|
|
432
|
-
});
|