Roll src/third_party/WebKit 3529d49:06e8485 (svn 202554:202555)
[chromium-blink-merge.git] / remoting / webapp / base / js / xmpp_login_handler_unittest.js
blob071ce4b74f48f0ba2a40a3a9a9a261e6fba2e4a1
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 (function() {
7 'use strict';
9 var testUsername = 'testUsername@gmail.com';
10 var testToken = 'testToken';
12 /** @type {(sinon.Spy|function(string):void)} */
13 var sendMessage_spy = function(msg) {};
14 /** @type {function(string):void} */
15 var sendMessage = function(msg) {};
17 /** @type {(sinon.Spy|function():void)} */
18 var startTls_spy = function() {};
19 /** @type {function():void} */
20 var startTls = function() {};
22 /** @type {(sinon.Spy|function(string, remoting.XmppStreamParser):void)} */
23 var onHandshakeDone_spy = function(name, parser) {};
24 /** @type {function(string, remoting.XmppStreamParser):void} */
25 var onHandshakeDone = function(name, parser) {};
27 /** @type {(sinon.Spy|function(remoting.Error, string):void)} */
28 var onError_spy = function(error, message) {};
29 /** @type {function(remoting.Error, string):void} */
30 var onError = function(error, message) {};
32 /** @type {remoting.XmppLoginHandler} */
33 var loginHandler = null;
35 QUnit.module('XmppLoginHandler', {
36   beforeEach: function() {
37     sendMessage_spy = sinon.spy();
38     sendMessage = /** @type {function(string):void} */ (sendMessage_spy);
39     startTls_spy = sinon.spy();
40     startTls = /** @type {function():void} */ (startTls_spy);
41     onHandshakeDone_spy = sinon.spy();
42     onHandshakeDone =
43           /** @type {function(string, remoting.XmppStreamParser):void} */
44           (onHandshakeDone_spy);
45     onError_spy = sinon.spy();
46     onError = /** @type {function(remoting.Error, string):void} */(onError_spy);
48     loginHandler = new remoting.XmppLoginHandler(
49         'google.com', testUsername, testToken,
50         remoting.TlsMode.WITHOUT_HANDSHAKE, sendMessage, startTls,
51         onHandshakeDone, onError);
52   }
53 });
55 // Executes handshake base.
56 function handshakeBase() {
57   loginHandler.start();
59   sinon.assert.calledWith(startTls);
60   startTls_spy.reset();
62   loginHandler.onTlsStarted();
63   var cookie = window.btoa("\0" + testUsername + "\0" + testToken);
64   sinon.assert.calledWith(
65       sendMessage,
66       '<stream:stream to="google.com" version="1.0" xmlns="jabber:client" ' +
67           'xmlns:stream="http://etherx.jabber.org/streams">' +
68       '<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="X-OAUTH2" ' +
69           'auth:service="oauth2" auth:allow-generated-jid="true" ' +
70           'auth:client-uses-full-bind-result="true" ' +
71           'auth:allow-non-google-login="true" ' +
72           'xmlns:auth="http://www.google.com/talk/protocol/auth">' + cookie +
73       '</auth>');
74   sendMessage_spy.reset();
76   loginHandler.onDataReceived(base.encodeUtf8(
77       '<stream:stream from="google.com" id="DCDDE5171CB2154A" version="1.0" ' +
78           'xmlns:stream="http://etherx.jabber.org/streams" ' +
79           'xmlns="jabber:client">' +
80         '<stream:features>' +
81           '<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">' +
82             '<mechanism>X-OAUTH2</mechanism>' +
83             '<mechanism>X-GOOGLE-TOKEN</mechanism>' +
84             '<mechanism>PLAIN</mechanism>' +
85           '</mechanisms>' +
86         '</stream:features>'));
89 QUnit.test('should authenticate', function() {
90   handshakeBase();
92   loginHandler.onDataReceived(
93       base.encodeUtf8('<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>'));
94   sinon.assert.calledWith(
95       sendMessage,
96       '<stream:stream to="google.com" version="1.0" xmlns="jabber:client" ' +
97           'xmlns:stream="http://etherx.jabber.org/streams">' +
98         '<iq type="set" id="0">' +
99           '<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">' +
100             '<resource>chromoting</resource>' +
101           '</bind>' +
102         '</iq>' +
103         '<iq type="set" id="1">' +
104           '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>' +
105         '</iq>');
106   sendMessage_spy.reset();
108   loginHandler.onDataReceived(base.encodeUtf8(
109       '<stream:stream from="google.com" id="104FA10576E2AA80" version="1.0" ' +
110           'xmlns:stream="http://etherx.jabber.org/streams" ' +
111           'xmlns="jabber:client">' +
112         '<stream:features>' +
113           '<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>' +
114           '<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>' +
115         '</stream:features>' +
116         '<iq id="0" type="result">' +
117           '<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">' +
118             '<jid>' + testUsername + '/chromoting52B4920E</jid>' +
119           '</bind>' +
120         '</iq>' +
121         '<iq type="result" id="1"/>'));
123   sinon.assert.calledWith(onHandshakeDone);
126 QUnit.test('use <starttls> handshake', function() {
127   loginHandler = new remoting.XmppLoginHandler(
128       'google.com', testUsername, testToken, remoting.TlsMode.WITH_HANDSHAKE,
129       sendMessage, startTls, onHandshakeDone, onError);
130   loginHandler.start();
132   sinon.assert.calledWith(
133       sendMessage,
134       '<stream:stream to="google.com" version="1.0" xmlns="jabber:client" ' +
135           'xmlns:stream="http://etherx.jabber.org/streams">' +
136           '<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>');
137   sendMessage_spy.reset();
139   loginHandler.onDataReceived(base.encodeUtf8(
140       '<stream:stream from="google.com" id="78A87C70559EF28A" version="1.0" ' +
141           'xmlns:stream="http://etherx.jabber.org/streams" ' +
142           'xmlns="jabber:client">' +
143         '<stream:features>' +
144           '<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls">' +
145             '<required/>' +
146           '</starttls>' +
147           '<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">' +
148             '<mechanism>X-OAUTH2</mechanism>' +
149             '<mechanism>X-GOOGLE-TOKEN</mechanism>' +
150           '</mechanisms>' +
151         '</stream:features>'));
153   loginHandler.onDataReceived(
154       base.encodeUtf8('<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>'));
156   sinon.assert.calledWith(startTls);
159 QUnit.test(
160     'should return AUTHENTICATION_FAILED error when failed to authenticate',
161     function() {
162   handshakeBase();
164   loginHandler.onDataReceived(
165       base.encodeUtf8('<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl">' +
166                       '<not-authorized/></failure>'));
167   sinon.assert.calledWith(onError, new remoting.Error(
168       remoting.Error.Tag.AUTHENTICATION_FAILED));
171 QUnit.test('should return UNEXPECTED error when failed to parse stream',
172      function() {
173   handshakeBase();
174   loginHandler.onDataReceived(
175       base.encodeUtf8('BAD DATA'));
176   sinon.assert.calledWith(onError, remoting.Error.unexpected());
179 })();