aboutsummaryrefslogtreecommitdiff
path: root/contexts/data/lib/closure-library/closure/goog/net/xpc/iframepollingtransport_test.html
blob: 16dda8531d3a00ece9825ae8b2ea15a4267bf705 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
<!DOCTYPE html>
<html>
<!--
Copyright 2012 The Closure Library Authors. All Rights Reserved.

Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<!--
-->
<head>
<meta http-equiv="X-IframePollingTransport-Compatible" content="IE=edge">
<title>NativeMessagingTransport Unit-Tests</title>
<script src="../../base.js"></script>
<script>
  goog.require('goog.Timer');
  goog.require('goog.dom');
  goog.require('goog.dom.TagName');
  goog.require('goog.functions');
  goog.require('goog.net.xpc');
  goog.require('goog.net.xpc.CrossPageChannel');
  goog.require('goog.net.xpc.CrossPageChannelRole');
  goog.require('goog.object');
  goog.require('goog.testing.MockClock');
  goog.require('goog.testing.jsunit');
  goog.require('goog.testing.recordFunction');
</script>
<script>

var mockClock = null;
var outerChannel = null;
var innerChannel = null;

function setUp() {
  mockClock = new goog.testing.MockClock(true /* opt_autoInstall */);

  // Create the peer windows.
  var outerPeerHostName = 'https://www.youtube.com';
  var outerPeerWindow = createMockPeerWindow(outerPeerHostName);

  var innerPeerHostName = 'https://www.google.com';
  var innerPeerWindow = createMockPeerWindow(innerPeerHostName);

  // Create the channels.
  outerChannel = createChannel(goog.net.xpc.CrossPageChannelRole.OUTER, 'test',
      outerPeerHostName, outerPeerWindow, innerPeerHostName, innerPeerWindow);
  innerChannel = createChannel(goog.net.xpc.CrossPageChannelRole.INNER, 'test',
      innerPeerHostName, innerPeerWindow, outerPeerHostName, outerPeerWindow);
};


function tearDown() {
  outerChannel.dispose();
  innerChannel.dispose();
  mockClock.uninstall();
};


/** Tests that connection happens normally and callbacks are invoked. */
function testConnect() {
  var outerConnectCallback = goog.testing.recordFunction();
  var innerConnectCallback = goog.testing.recordFunction();

  // Connect the two channels.
  outerChannel.connect(outerConnectCallback);
  innerChannel.connect(innerConnectCallback);
  mockClock.tick(1000);

  // Check that channels were connected and callbacks invoked.
  assertEquals(1, outerConnectCallback.getCallCount());
  assertEquals(1, innerConnectCallback.getCallCount());
  assertTrue(outerChannel.isConnected());
  assertTrue(innerChannel.isConnected());
};


/** Tests that messages are successfully delivered to the inner peer. */
function testSend_outerToInner() {
  var serviceCallback = goog.testing.recordFunction();

  // Register a service handler in the inner channel.
  innerChannel.registerService('svc', function(payload) {
    assertEquals('hello', payload);
    serviceCallback();
  });

  // Connect the two channels.
  outerChannel.connect();
  innerChannel.connect();
  mockClock.tick(1000);

  // Send a message.
  outerChannel.send('svc', 'hello');
  mockClock.tick(1000);

  // Check that the message was handled.
  assertEquals(1, serviceCallback.getCallCount());
};


/** Tests that messages are successfully delivered to the outer peer. */
function testSend_innerToOuter() {
  var serviceCallback = goog.testing.recordFunction();

  // Register a service handler in the inner channel.
  outerChannel.registerService('svc', function(payload) {
    assertEquals('hello', payload);
    serviceCallback();
  });

  // Connect the two channels.
  outerChannel.connect();
  innerChannel.connect();
  mockClock.tick(1000);

  // Send a message.
  innerChannel.send('svc', 'hello');
  mockClock.tick(1000);

  // Check that the message was handled.
  assertEquals(1, serviceCallback.getCallCount());
};


/** Tests that closing the outer peer does not cause an error. */
function testSend_outerPeerClosed() {
  // Connect the inner channel.
  innerChannel.connect();
  mockClock.tick(1000);

  // Close the outer peer before it has a chance to connect.
  closeWindow(innerChannel.getPeerWindowObject());

  // Allow timers to execute (and fail).
  mockClock.tick(1000);
};


/** Tests that closing the inner peer does not cause an error. */
function testSend_innerPeerClosed() {
  // Connect the outer channel.
  outerChannel.connect();
  mockClock.tick(1000);

  // Close the inner peer before it has a chance to connect.
  closeWindow(outerChannel.getPeerWindowObject());

  // Allow timers to execute (and fail).
  mockClock.tick(1000);
};


/** Tests that partially closing the outer peer does not cause an error. */
function testSend_outerPeerClosing() {
  // Connect the inner channel.
  innerChannel.connect();
  mockClock.tick(1000);

  // Close the outer peer before it has a chance to connect, but
  // leave closed set to false to simulate a partially closed window.
  closeWindow(innerChannel.getPeerWindowObject());
  innerChannel.getPeerWindowObject().closed = false;

  // Allow timers to execute (and fail).
  mockClock.tick(1000);
};


/** Tests that partially closing the inner peer does not cause an error. */
function testSend_innerPeerClosing() {
  // Connect the outer channel.
  outerChannel.connect();
  mockClock.tick(1000);

  // Close the inner peer before it has a chance to connect, but
  // leave closed set to false to simulate a partially closed window.
  closeWindow(outerChannel.getPeerWindowObject());
  outerChannel.getPeerWindowObject().closed = false;

  // Allow timers to execute (and fail).
  mockClock.tick(1000);
};


/**
 * Creates a channel with the specified configuration, using frame polling.
 * @param {!goog.net.xpc.CrossPageChannelRole} role The channel role.
 * @param {string} channelName The channel name.
 * @param {string} fromHostName The host name of the window hosting the channel.
 * @param {!Object} fromWindow The window hosting the channel.
 * @param {string} toHostName The host name of the peer window.
 * @param {!Object} toWindow The peer window.
 */
function createChannel(role, channelName, fromHostName, fromWindow, toHostName,
    toWindow) {

  // Build a channel config using frame polling.
  var channelConfig = goog.object.create(
      goog.net.xpc.CfgFields.ROLE,
      role,
      goog.net.xpc.CfgFields.PEER_HOSTNAME,
      toHostName,
      goog.net.xpc.CfgFields.CHANNEL_NAME,
      channelName,
      goog.net.xpc.CfgFields.LOCAL_POLL_URI,
      fromHostName + '/robots.txt',
      goog.net.xpc.CfgFields.PEER_POLL_URI,
      toHostName + '/robots.txt',
      goog.net.xpc.CfgFields.TRANSPORT,
      goog.net.xpc.TransportTypes.IFRAME_POLLING);

  // Build the channel.
  var channel = new goog.net.xpc.CrossPageChannel(channelConfig);
  channel.setPeerWindowObject(toWindow);

  // Update the transport's getWindow, to return the correct host window.
  channel.createTransport_();
  channel.transport_.getWindow = goog.functions.constant(fromWindow);
  return channel;
};


/**
 * Creates a mock window to use as a peer. The peer window will host the frame
 * elements.
 * @param {string} url The peer window's initial URL.
 */
function createMockPeerWindow(url) {
  var mockPeer = createMockWindow(url);

  // Update the appendChild method to use a mock frame window.
  mockPeer.document.body.appendChild = function(el) {
    assertEquals(goog.dom.TagName.IFRAME, el.tagName);
    mockPeer.frames[el.name] = createMockWindow(el.src);
    mockPeer.document.body.element.appendChild(el);
  };

  return mockPeer;
};


/**
 * Creates a mock window.
 * @param {string} url The window's initial URL.
 */
function createMockWindow(url) {
  // Create the mock window, document and body.
  var mockWindow = {};
  var mockDocument = {};
  var mockBody = {};
  var mockLocation = {};

  // Configure the mock window's document body.
  mockBody.element = goog.dom.createDom(goog.dom.TagName.BODY);

  // Configure the mock window's document.
  mockDocument.body = mockBody;

  // Configure the mock window's location.
  mockLocation.href = url;
  mockLocation.replace = function(value) { mockLocation.href = value; }

  // Configure the mock window.
  mockWindow.document = mockDocument;
  mockWindow.frames = {};
  mockWindow.location = mockLocation;
  mockWindow.setTimeout = goog.Timer.callOnce;

  return mockWindow;
};


/**
 * Emulates closing the specified window by clearing frames, document and
 * location.
 */
function closeWindow(targetWindow) {
  // Close any child frame windows.
  for (var frameName in targetWindow.frames) {
    closeWindow(targetWindow.frames[frameName]);
  }

  // Clear the target window, set closed to true.
  targetWindow.closed = true;
  targetWindow.frames = null;
  targetWindow.document = null;
  targetWindow.location = null;
};

</script>
</head>

<body></body>

</html>