OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview | 6 * @fileoverview |
7 * TODO(garykac): Create interface for SignalStrategy. | 7 * TODO(garykac): Create interface for SignalStrategy. |
8 * @suppress {checkTypes|checkVars|reportUnknownTypes|visibility} | 8 * @suppress {checkTypes|checkVars|reportUnknownTypes|visibility} |
9 */ | 9 */ |
10 | 10 |
11 (function() { | 11 (function() { |
12 | 12 |
13 'use strict'; | 13 'use strict'; |
14 | 14 |
15 /** @type {(sinon.Spy|function(remoting.SignalStrategy.State))} */ | 15 /** @type {(sinon.Spy|function(remoting.SignalStrategy.State))} */ |
16 var onStateChange = null; | 16 var onStateChange = null; |
17 | 17 |
18 /** @type {(sinon.Spy|function(Element):void)} */ | 18 /** @type {(sinon.Spy|function(Element):void)} */ |
19 var onIncomingStanzaCallback = null; | 19 var onIncomingStanzaCallback = null; |
20 | 20 |
21 /** @type {remoting.DnsBlackholeChecker} */ | 21 /** @type {remoting.DnsBlackholeChecker} */ |
22 var checker = null; | 22 var checker = null; |
23 | 23 |
24 /** @type {remoting.MockSignalStrategy} */ | 24 /** @type {remoting.MockSignalStrategy} */ |
25 var signalStrategy = null; | 25 var signalStrategy = null; |
26 var fakeXhrs; | 26 var fakeXhrs; |
27 | 27 |
28 module('dns_blackhole_checker', { | 28 QUnit.module('dns_blackhole_checker', { |
29 setup: function() { | 29 setup: function() { |
30 fakeXhrs = []; | 30 fakeXhrs = []; |
31 sinon.useFakeXMLHttpRequest().onCreate = function(xhr) { | 31 sinon.useFakeXMLHttpRequest().onCreate = function(xhr) { |
32 fakeXhrs.push(xhr); | 32 fakeXhrs.push(xhr); |
33 }; | 33 }; |
34 | 34 |
35 onStateChange = sinon.spy(); | 35 onStateChange = sinon.spy(); |
36 onIncomingStanzaCallback = sinon.spy(); | 36 onIncomingStanzaCallback = sinon.spy(); |
37 signalStrategy = new remoting.MockSignalStrategy(); | 37 signalStrategy = new remoting.MockSignalStrategy(); |
38 checker = new remoting.DnsBlackholeChecker(signalStrategy); | 38 checker = new remoting.DnsBlackholeChecker(signalStrategy); |
(...skipping 13 matching lines...) Expand all Loading... |
52 'the correct URL is requested'); | 52 'the correct URL is requested'); |
53 }, | 53 }, |
54 teardown: function() { | 54 teardown: function() { |
55 base.dispose(checker); | 55 base.dispose(checker); |
56 sinon.assert.calledWith(onStateChange, | 56 sinon.assert.calledWith(onStateChange, |
57 remoting.SignalStrategy.State.CLOSED); | 57 remoting.SignalStrategy.State.CLOSED); |
58 | 58 |
59 onStateChange = null; | 59 onStateChange = null; |
60 onIncomingStanzaCallback = null; | 60 onIncomingStanzaCallback = null; |
61 checker = null; | 61 checker = null; |
62 }, | 62 } |
63 }); | 63 }); |
64 | 64 |
| 65 function await(condition) { |
| 66 function loop(count) { |
| 67 if (condition()) { |
| 68 return Promise.resolve(); |
| 69 } else if (count > 1000) { |
| 70 return Promise.reject('condition never became true'); |
| 71 } else { |
| 72 return Promise.resolve().then(loop.bind(null, count + 1)); |
| 73 } |
| 74 }; |
| 75 return loop(0); |
| 76 }; |
| 77 |
65 test('success', | 78 test('success', |
66 function() { | 79 function() { |
67 fakeXhrs[0].respond(200); | 80 function checkState(state) { |
68 sinon.assert.notCalled(onStateChange); | 81 return SpyPromise.run(function() { |
| 82 signalStrategy.setStateForTesting(state); |
| 83 }).then(function() { |
| 84 sinon.assert.calledWith(onStateChange, state); |
| 85 equal(checker.getState(), state); |
| 86 }); |
| 87 }; |
69 | 88 |
70 [ | 89 return SpyPromise.run(function() { |
71 remoting.SignalStrategy.State.CONNECTING, | 90 fakeXhrs[0].respond(200); |
72 remoting.SignalStrategy.State.HANDSHAKE, | 91 }).then(function() { |
73 remoting.SignalStrategy.State.CONNECTED | 92 sinon.assert.notCalled(onStateChange); |
74 ].forEach(function(state) { | 93 }). |
75 signalStrategy.setStateForTesting(state); | 94 then(checkState.bind(null, remoting.SignalStrategy.State.CONNECTING)). |
76 sinon.assert.calledWith(onStateChange, state); | 95 then(checkState.bind(null, remoting.SignalStrategy.State.HANDSHAKE)). |
77 equal(checker.getState(), state); | 96 then(checkState.bind(null, remoting.SignalStrategy.State.CONNECTED)); |
| 97 }); |
| 98 |
| 99 test('http response after connected', |
| 100 function() { |
| 101 function checkState(state) { |
| 102 return SpyPromise.run(function() { |
| 103 signalStrategy.setStateForTesting(state); |
| 104 }).then(function() { |
| 105 sinon.assert.calledWith(onStateChange, state); |
| 106 equal(checker.getState(), state); |
| 107 }); |
| 108 } |
| 109 |
| 110 return Promise.resolve().then(function() { |
| 111 return checkState(remoting.SignalStrategy.State.CONNECTING); |
| 112 }).then(function() { |
| 113 return checkState(remoting.SignalStrategy.State.HANDSHAKE); |
| 114 }).then(function() { |
| 115 onStateChange.reset(); |
| 116 |
| 117 // Verify that DnsBlackholeChecker stays in HANDSHAKE state even if the |
| 118 // signal strategy has connected. |
| 119 return SpyPromise.run(function() { |
| 120 signalStrategy.setStateForTesting( |
| 121 remoting.SignalStrategy.State.CONNECTED); |
| 122 }); |
| 123 }).then(function() { |
| 124 sinon.assert.notCalled(onStateChange); |
| 125 equal(checker.getState(), remoting.SignalStrategy.State.HANDSHAKE); |
| 126 |
| 127 // Verify that DnsBlackholeChecker goes to CONNECTED state after the |
| 128 // the HTTP request has succeeded. |
| 129 return SpyPromise.run(function() { |
| 130 fakeXhrs[0].respond(200); |
| 131 }); |
| 132 }).then(function() { |
| 133 sinon.assert.calledWith(onStateChange, |
| 134 remoting.SignalStrategy.State.CONNECTED); |
| 135 }); |
| 136 }); |
| 137 |
| 138 QUnit.test('connect failed', |
| 139 function() { |
| 140 function checkState(state) { |
| 141 return SpyPromise.run(function() { |
| 142 signalStrategy.setStateForTesting(state); |
| 143 }).then(function() { |
| 144 sinon.assert.calledWith(onStateChange, state); |
| 145 }); |
| 146 }; |
| 147 |
| 148 return SpyPromise.run(function() { |
| 149 fakeXhrs[0].respond(200); |
| 150 }).then(function() { |
| 151 sinon.assert.notCalled(onStateChange); |
| 152 }). |
| 153 then(checkState.bind(null, remoting.SignalStrategy.State.CONNECTING)). |
| 154 then(checkState.bind(null, remoting.SignalStrategy.State.FAILED)); |
| 155 }); |
| 156 |
| 157 QUnit.test('blocked', |
| 158 function(assert) { |
| 159 function checkState(state) { |
| 160 onStateChange.reset(); |
| 161 return SpyPromise.run(function() { |
| 162 signalStrategy.setStateForTesting(state); |
| 163 }).then(function() { |
| 164 sinon.assert.notCalled(onStateChange); |
| 165 assert.equal( |
| 166 checker.getState(), |
| 167 remoting.SignalStrategy.State.FAILED, |
| 168 'checker state is still FAILED'); |
| 169 }); |
| 170 }; |
| 171 |
| 172 return SpyPromise.run(function() { |
| 173 fakeXhrs[0].respond(400); |
| 174 }).then(function() { |
| 175 sinon.assert.calledWith( |
| 176 onStateChange, remoting.SignalStrategy.State.FAILED); |
| 177 assert.equal( |
| 178 checker.getError().tag, |
| 179 remoting.Error.Tag.NOT_AUTHORIZED, |
| 180 'checker error is NOT_AUTHORIZED'); |
| 181 }). |
| 182 then(checkState.bind(null, remoting.SignalStrategy.State.CONNECTING)). |
| 183 then(checkState.bind(null, remoting.SignalStrategy.State.HANDSHAKE)). |
| 184 then(checkState.bind(null, remoting.SignalStrategy.State.CONNECTED)); |
| 185 }); |
| 186 |
| 187 QUnit.test('blocked after connected', |
| 188 function() { |
| 189 function checkState(state) { |
| 190 return SpyPromise.run(function() { |
| 191 signalStrategy.setStateForTesting(state); |
| 192 }).then(function() { |
| 193 sinon.assert.calledWith(onStateChange, state); |
| 194 equal(checker.getState(), state); |
| 195 }); |
| 196 }; |
| 197 |
| 198 return Promise.resolve().then(function() { |
| 199 return checkState(remoting.SignalStrategy.State.CONNECTING); |
| 200 }).then(function() { |
| 201 return checkState(remoting.SignalStrategy.State.HANDSHAKE); |
| 202 }).then(function() { |
| 203 onStateChange.reset(); |
| 204 |
| 205 // Verify that DnsBlackholeChecker stays in HANDSHAKE state even |
| 206 // if the signal strategy has connected. |
| 207 return SpyPromise.run(function() { |
| 208 signalStrategy.setStateForTesting( |
| 209 remoting.SignalStrategy.State.CONNECTED); |
| 210 }); |
| 211 }).then(function() { |
| 212 sinon.assert.notCalled(onStateChange); |
| 213 equal(checker.getState(), remoting.SignalStrategy.State.HANDSHAKE); |
| 214 |
| 215 // Verify that DnsBlackholeChecker goes to FAILED state after it |
| 216 // gets the blocked HTTP response. |
| 217 return SpyPromise.run(function() { |
| 218 fakeXhrs[0].respond(400); |
| 219 }); |
| 220 }).then(function() { |
| 221 sinon.assert.calledWith(onStateChange, |
| 222 remoting.SignalStrategy.State.FAILED); |
| 223 equal(checker.getError().tag, remoting.Error.Tag.NOT_AUTHORIZED); |
78 }); | 224 }); |
79 } | 225 } |
80 ); | 226 ); |
81 | 227 |
82 test('http response after connected', | |
83 function() { | |
84 [ | |
85 remoting.SignalStrategy.State.CONNECTING, | |
86 remoting.SignalStrategy.State.HANDSHAKE, | |
87 ].forEach(function(state) { | |
88 signalStrategy.setStateForTesting(state); | |
89 sinon.assert.calledWith(onStateChange, state); | |
90 equal(checker.getState(), state); | |
91 }); | |
92 onStateChange.reset(); | |
93 | |
94 // Verify that DnsBlackholeChecker stays in HANDSHAKE state even if the | |
95 // signal strategy has connected. | |
96 signalStrategy.setStateForTesting(remoting.SignalStrategy.State.CONNECTED); | |
97 sinon.assert.notCalled(onStateChange); | |
98 equal(checker.getState(), remoting.SignalStrategy.State.HANDSHAKE); | |
99 | |
100 // Verify that DnsBlackholeChecker goes to CONNECTED state after the | |
101 // the HTTP request has succeeded. | |
102 fakeXhrs[0].respond(200); | |
103 sinon.assert.calledWith(onStateChange, | |
104 remoting.SignalStrategy.State.CONNECTED); | |
105 } | |
106 ); | |
107 | |
108 test('connect failed', | |
109 function() { | |
110 fakeXhrs[0].respond(200); | |
111 sinon.assert.notCalled(onStateChange); | |
112 | |
113 [ | |
114 remoting.SignalStrategy.State.CONNECTING, | |
115 remoting.SignalStrategy.State.FAILED | |
116 ].forEach(function(state) { | |
117 signalStrategy.setStateForTesting(state); | |
118 sinon.assert.calledWith(onStateChange, state); | |
119 }); | |
120 } | |
121 ); | |
122 | |
123 test('blocked', | |
124 function() { | |
125 fakeXhrs[0].respond(400); | |
126 sinon.assert.calledWith(onStateChange, | |
127 remoting.SignalStrategy.State.FAILED); | |
128 equal(checker.getError().tag, remoting.Error.Tag.NOT_AUTHORIZED); | |
129 onStateChange.reset(); | |
130 | |
131 [ | |
132 remoting.SignalStrategy.State.CONNECTING, | |
133 remoting.SignalStrategy.State.HANDSHAKE, | |
134 remoting.SignalStrategy.State.CONNECTED | |
135 ].forEach(function(state) { | |
136 signalStrategy.setStateForTesting(state); | |
137 sinon.assert.notCalled(onStateChange); | |
138 equal(checker.getState(), remoting.SignalStrategy.State.FAILED); | |
139 }); | |
140 } | |
141 ); | |
142 | |
143 test('blocked after connected', | |
144 function() { | |
145 [ | |
146 remoting.SignalStrategy.State.CONNECTING, | |
147 remoting.SignalStrategy.State.HANDSHAKE, | |
148 ].forEach(function(state) { | |
149 signalStrategy.setStateForTesting(state); | |
150 sinon.assert.calledWith(onStateChange, state); | |
151 equal(checker.getState(), state); | |
152 }); | |
153 onStateChange.reset(); | |
154 | |
155 // Verify that DnsBlackholeChecker stays in HANDSHAKE state even if the | |
156 // signal strategy has connected. | |
157 signalStrategy.setStateForTesting(remoting.SignalStrategy.State.CONNECTED); | |
158 sinon.assert.notCalled(onStateChange); | |
159 equal(checker.getState(), remoting.SignalStrategy.State.HANDSHAKE); | |
160 | |
161 // Verify that DnsBlackholeChecker goes to FAILED state after it gets the | |
162 // blocked HTTP response. | |
163 fakeXhrs[0].respond(400); | |
164 sinon.assert.calledWith(onStateChange, | |
165 remoting.SignalStrategy.State.FAILED); | |
166 equal(checker.getError().tag, remoting.Error.Tag.NOT_AUTHORIZED); | |
167 } | |
168 ); | |
169 | |
170 })(); | 228 })(); |
OLD | NEW |