aboutsummaryrefslogtreecommitdiff
path: root/contexts/data/lib/closure-library/closure/goog/window/window_test.html
blob: ac0e40b8ef57dceea19d0b30cc4d48ddaf7596aa (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
<!DOCTYPE html>
<html>
<!--
Copyright 2009 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.
-->
<!--

  @author marcosalmeida@google.com (Marcos Almeida)
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.window</title>
<script src="../base.js"></script>
<script>
  goog.require('goog.dom');
  goog.require('goog.events');
  goog.require('goog.string');
  goog.require('goog.testing.AsyncTestCase');
  goog.require('goog.testing.jsunit');
  goog.require('goog.window');
</script>
<style type='text/css'>

.goog-like-link {
  color: blue;
  text-decoration: underline;
  cursor: pointer;
}

</style>
</head>
<body>

<h4>Some links for testing referrer stripping manually.</h4>
<div class='goog-like-link'>http://www.google.com/search?q=;</div>
<div class='goog-like-link'>http://www.google.com/search?q=x&amp;lang=en</div>
<div class='goog-like-link'>http://www.google.com/search?q=x;lang=en</div>
<div class='goog-like-link'>http://www.google.com/search?q="</div>
<div class='goog-like-link'>http://www.google.com/search?q='</div>
<div class='goog-like-link'>http://www.google.com/search?q=&lt;</div>
<div class='goog-like-link'>http://www.google.com/search?q=&gt;</div>

<script>

  var newWin;
  var REDIRECT_URL_PREFIX = 'window_test.html?runTests=';
  var asyncTestCase =
      goog.testing.AsyncTestCase.createAndInstall(document.title);
  asyncTestCase.stepTimeout = 5000;

  var WIN_LOAD_TRY_TIMEOUT = 100;
  var MAX_WIN_LOAD_TRIES = 50; // 50x100ms = 5s waiting for window to load.
  var winLoadCounter;

  function setUpPage() {
    var anchors = goog.dom.getElementsByTagNameAndClass(
        'div', 'goog-like-link');
    for (var i = 0; i < anchors.length; i++) {
      goog.events.listen(
          anchors[i], 'click',
          function(e) {
            goog.window.open(
                goog.dom.getTextContent(e.target), {'noreferrer': true});
          });
    }
  }

  /**
   * Some tests should only run locally, because they will trigger
   * popup blockers on http urls.
   */
  function canOpenPopups() {
    // TODO(nicksantos): Fix the test runner farm.
    return window.location.toString().indexOf('file://') == 0;
  }

  if (canOpenPopups()) {
    // To test goog.window.open we open a new window with this file again. Once
    // the new window gets to this point in the file it notifies the opener that
    // it has loaded, so that the opener knows that the new window has been
    // populated with properties like referrer and location.
    var newWinLoaded = false;
    if (window.opener && window.opener.newWinLoaded === false) {
      window.opener.newWinLoaded = true;
    }
  }

  function setUp() {
    newWinLoaded = false;
  }

  function tearDown() {
    if (newWin) {
      newWin.close();
    }
  }

  /**
   * Uses setTimeout to keep checking if a new window has been loaded, and once
   * it has, calls the given continuation function and then calls
   * asyncTestCase.continueTesting() to resume the flow of the test.
   * @param {Function} continueFn Continuation function to be called when the
   *     new window has loaded.
   * @param {number=} opt_numTries Number of times this method has checked if
   *     the window has loaded, to prevent getting in an endless setTimeout
   *     loop. (Used internally, callers should omit.)
   */
  function continueAfterWindowLoaded(continueFn, opt_numTries) {
    opt_numTries = opt_numTries || 0;
    if (newWinLoaded) {
      continueFn();
      asyncTestCase.continueTesting();
    } else if (opt_numTries > MAX_WIN_LOAD_TRIES) {
      fail('Window did not load after maximum number of checks.');
      asyncTestCase.continueTesting();
    } else {
      setTimeout(goog.partial(continueAfterWindowLoaded,
                              continueFn, ++opt_numTries),
                 WIN_LOAD_TRY_TIMEOUT);
    }
  }

  /**
   * Helper to kick off a test that opens a window and checks that the referrer
   * is hidden if requested and the url is properly encoded/decoded.
   * @param {boolean} noreferrer Whether to test the noreferrer option.
   * @param {string} urlParam Url param to append to the url being opened.
   */
  function doTestOpenWindow(noreferrer, urlParam) {
    if (!canOpenPopups()) {
      return;
    }
    newWin = goog.window.open(REDIRECT_URL_PREFIX + urlParam,
                              {'noreferrer': noreferrer});
    asyncTestCase.waitForAsync('Waiting for window to open and load.');
    continueAfterWindowLoaded(
        goog.partial(continueTestOpenWindow, noreferrer, urlParam));
  }

  /**
   * Helper callback to do asserts after the window opens.
   * @param noreferrer Whether the noreferrer option is being tested.
   * @param urlParam Url param appended to the url being opened.
   */
  function continueTestOpenWindow(noreferrer, urlParam) {
    if (noreferrer) {
      assertEquals('Referrer should have been stripped',
                   '', newWin.document.referrer);
    }

    var newWinUrl = decodeURI(newWin.location);
    var expectedUrlSuffix = decodeURI(urlParam);
    assertTrue('New window href should have ended with <' + expectedUrlSuffix +
        '> but was <' + newWinUrl + '>',
        goog.string.endsWith(newWinUrl, expectedUrlSuffix));
  }


  function testOpenNotEncoded() {
    doTestOpenWindow(false, '"bogus~"');
  }

  function testOpenEncoded() {
    doTestOpenWindow(false, '"bogus%7E"');
  }

  function testOpenEncodedPercent() {
    // Intent of url is to pass %7E to the server, so it was encoded to %257E .
    doTestOpenWindow(false, '"bogus%257E"');
  }

  function testOpenNotEncodedHidingReferrer() {
    doTestOpenWindow(true, '"bogus~"');
  }

  function testOpenEncodedHidingReferrer() {
    doTestOpenWindow(true, '"bogus%7E"');
  }

  function testOpenEncodedPercentHidingReferrer() {
    // Intent of url is to pass %7E to the server, so it was encoded to %257E .
    doTestOpenWindow(true, '"bogus%257E"');
  }

  function testOpenSemicolon() {
    doTestOpenWindow(true,  "beforesemi;aftersemi");
  }

  function testTwoSemicolons() {
    doTestOpenWindow(true,  "a;b;c");
  }

  function testOpenAmpersand() {
    doTestOpenWindow(true,  "this&that");
  }

  function testOpenSingleQuote() {
    doTestOpenWindow(true,  "'");
  }

  function testOpenDoubleQuote() {
    doTestOpenWindow(true,  '"');
  }

  function testOpenDoubleQuote() {
    doTestOpenWindow(true,  '<');
  }

  function testOpenDoubleQuote() {
    doTestOpenWindow(true,  '>');
  }

  function testOpenBlank() {
    if (!canOpenPopups()) {
      return;
    }
    newWin = goog.window.openBlank('Loading...');
    asyncTestCase.waitForAsync('Waiting for temp window to open and load.');
    var urlParam = 'bogus~';

    var continueFn = function() {
      newWin.location.href = REDIRECT_URL_PREFIX + urlParam;
      continueAfterWindowLoaded(
          goog.partial(continueTestOpenWindow, false, urlParam));
    }
    setTimeout(continueFn, 100);
  }

  /** @this {Element} */
  function stripReferrer() {
    goog.window.open(this.href, {'noreferrer': true});
  }

</script>
</body>
</html>