blob: fa7d77f6114f6bc57b792f2e4678ea74d9e3738c [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
goog.module('mr.dial.ClientTest');
goog.setTestOnly('mr.dial.ClientTest');
const DialClient = goog.require('mr.dial.Client');
const DialSink = goog.require('mr.dial.Sink');
const XhrUtils = goog.require('mr.XhrUtils');
describe('Dial Client Tests', function() {
let client;
let mockXhrManager;
let sink;
const appUrl = 'http://198.0.0.100/apps';
beforeEach(function() {
sink = new DialSink('sink', 'sinkid');
sink.setDialAppUrl(appUrl);
mockXhrManager = jasmine.createSpyObj('XhrManager', ['send']);
spyOn(XhrUtils, 'logRawXhr');
client = new DialClient.Client(sink, mockXhrManager);
});
const setMockXhrResponse = function(xml) {
mockXhrManager.send.and.returnValue(
Promise.resolve({responseText: xml, status: 200}));
};
const setMockXhrErrorResponse = function() {
mockXhrManager.send.and.returnValue(
Promise.resolve({responseText: null, status: 403 /* Forbidden */}));
};
const setMockXhrNotFoundResponse = function() {
mockXhrManager.send.and.returnValue(
Promise.resolve({responseText: null, status: 404}));
};
const setMockXhrReject = function() {
mockXhrManager.send.and.returnValue(
Promise.reject(new Error('send failed')));
};
// Suppress Jasmine warning about a spec with no expectations.
const noExpectations = function() {
expect(true).toBe(true);
};
describe('Tests launchApp', function() {
const expectLaunchAppFails = function(done) {
client.launchApp('YouTube', 'v=12345678').then(() => {
fail('launchApp unexpectedly succeeded.');
}, () => done());
};
it('Resolves', done => {
setMockXhrResponse('');
client.launchApp('YouTube', 'v=12345678').then(() => {
expect(mockXhrManager.send)
.toHaveBeenCalledWith(
appUrl + '/YouTube', 'POST', 'v=12345678', jasmine.any(Object));
done();
});
});
it('Rejects on error response', done => {
setMockXhrErrorResponse();
expectLaunchAppFails(done);
noExpectations();
});
it('Rejects on send rejection', done => {
setMockXhrReject();
expectLaunchAppFails(done);
noExpectations();
});
});
describe('Tests stopApp', function() {
const expectStopAppFails = function(done) {
client.stopApp('YouTube').then(() => {
fail('stopApp unexpectedly succeeded.');
}, () => done());
};
it('Resolves', done => {
// Set up the mock response for the GET request.
setMockXhrResponse(VALID_GET_RESPONSE_);
client.stopApp('YouTube').then(() => {
expect(mockXhrManager.send.calls.count()).toEqual(2);
expect(mockXhrManager.send.calls.argsFor(0)[0])
.toEqual(appUrl + '/YouTube');
expect(mockXhrManager.send.calls.argsFor(0)[1]).toEqual('GET');
expect(mockXhrManager.send.calls.argsFor(1)[0])
.toEqual(appUrl + '/YouTube/run');
expect(mockXhrManager.send.calls.argsFor(1)[1]).toEqual('DELETE');
done();
});
});
it('Resolves with fallback path', done => {
mockXhrManager.send.and.callFake((url, method) => {
if (method === 'GET') {
return Promise.reject(new Error('GET failed'));
} else {
return Promise.resolve({status: 200});
}
});
client.stopApp('YouTube').then(() => {
expect(mockXhrManager.send.calls.count()).toEqual(2);
expect(mockXhrManager.send.calls.argsFor(1)[0])
.toEqual(appUrl + '/YouTube/run');
expect(mockXhrManager.send.calls.argsFor(1)[1]).toEqual('DELETE');
done();
});
});
it('Rejects on error response', done => {
setMockXhrErrorResponse();
expectStopAppFails(done);
noExpectations();
});
it('Rejects on send rejection', done => {
setMockXhrReject();
expectStopAppFails(done);
noExpectations();
});
});
const expectMockSendGet = function() {
expect(mockXhrManager.send)
.toHaveBeenCalledWith(
'http://198.0.0.100/apps/YouTube', 'GET', undefined,
jasmine.any(Object));
};
const VALID_GET_RESPONSE_ = '<?xml version="1.0" encoding="UTF-8"?>' +
'<service xmlns="urn:dial-multiscreen-org:schemas:dial">' +
'<name>YouTube</name>' +
'<options allowStop="false"/>' +
'<state>running</state>' +
'<link rel="run" href="run"/>' +
'</service>';
const VALID_GET_RESPONSE_EXTRA_DATA_ =
'<?xml version="1.0" encoding="UTF-8"?>' +
'<service xmlns="urn:dial-multiscreen-org:schemas:dial" xmlns:atom="http://www.w3.org/2005/Atom">' +
'<name>YouTube</name>' +
'<state>running</state>' +
'<atom:link rel="run" href="run"/>' +
'<port>8080</port>' +
'<additionalData>' +
'<screenId>e5n3112oskr42pg0td55b38nh4</screenId>' +
'<otherField>2</otherField>' +
'</additionalData>' +
'</service>';
const INVALID_GET_RESPONSE_NO_SERVICE_ =
'<?xml version="1.0" encoding="UTF-8"?>';
const INVALID_GET_RESPONSE_NO_STATE_ =
'<?xml version="1.0" encoding="UTF-8"?>' +
'<service xmlns="urn:dial-multiscreen-org:schemas:dial">' +
'<name>YouTube</name>' +
'<options allowStop="true"/>' +
'<link rel="run" href="run"/>' +
'</service>';
const INVALID_GET_RESPONSE_INVALID_STATE_ =
'<?xml version="1.0" encoding="UTF-8"?>' +
'<service xmlns="urn:dial-multiscreen-org:schemas:dial">' +
'<name>YouTube</name>' +
'<options allowStop="true"/>' +
'<state>xyzzy</state>' +
'<link rel="run" href="run"/>' +
'</service>';
const INVALID_GET_RESPONSE_INSTALLABLE_ =
'<?xml version="1.0" encoding="UTF-8"?>' +
'<service xmlns="urn:dial-multiscreen-org:schemas:dial">' +
'<name>YouTube</name>' +
'<options allowStop="true"/>' +
'<state>installable=http://play.google.com/youtube</state>' +
'<link rel="run" href="run"/>' +
'</service>';
const INVALID_GET_RESPONSE_NO_NAME_ =
'<?xml version="1.0" encoding="UTF-8"?>' +
'<service xmlns="urn:dial-multiscreen-org:schemas:dial">' +
'<options allowStop="true"/>' +
'<state>running</state>' +
'<link rel="run" href="run"/>' +
'</service>';
const INVALID_GET_RESPONSE_WRONG_APP_NAME_ =
'<?xml version="1.0" encoding="UTF-8"?>' +
'<service xmlns="urn:dial-multiscreen-org:schemas:dial">' +
'<name>WrongAppName</name>' +
'<options allowStop="true"/>' +
'<state>running</state>' +
'<link rel="run" href="run"/>' +
'</service>';
describe('Tests getAppInfo', function() {
it('Returns info from valid response', done => {
setMockXhrResponse(VALID_GET_RESPONSE_);
client.getAppInfo('YouTube').then(appInfo => {
expect(appInfo.name).toEqual('YouTube');
expect(appInfo.state).toEqual('running');
expect(appInfo.allowStop).toBe(false);
expect(appInfo.resource).toEqual('run');
expectMockSendGet();
done();
});
});
it('Returns info with extraData', done => {
setMockXhrResponse(VALID_GET_RESPONSE_EXTRA_DATA_);
client.getAppInfo('YouTube').then(appInfo => {
expect(appInfo.name).toEqual('YouTube');
expect(appInfo.state).toEqual('running');
expect(appInfo.allowStop).toBe(true);
expect(appInfo.resource).toEqual('run');
expect(appInfo.extraData.port).toEqual('8080');
expect(appInfo.extraData.additionalData)
.toEqual(
'<screenId xmlns="urn:dial-multiscreen-org:schemas:dial">' +
'e5n3112oskr42pg0td55b38nh4</screenId>' +
'<otherField xmlns="urn:dial-multiscreen-org:schemas:dial">2' +
'</otherField>');
expectMockSendGet();
done();
});
});
const expectGetAppInfoFails = function(done) {
client.getAppInfo('YouTube').then(
_ => {
fail('getAppInfo unexpectedly succeeded.');
},
e => {
expectMockSendGet();
done();
});
};
const testInvalidResponse = function(response, done) {
setMockXhrResponse(response);
expectGetAppInfoFails(done);
};
it('Rejects on invalid response 1', done => {
testInvalidResponse('blarg', done);
});
it('Rejects on invalid response 2', done => {
testInvalidResponse(INVALID_GET_RESPONSE_NO_SERVICE_, done);
});
it('Rejects on invalid response 3', done => {
testInvalidResponse(INVALID_GET_RESPONSE_NO_STATE_, done);
});
it('Rejects on invalid response 4', done => {
testInvalidResponse(INVALID_GET_RESPONSE_NO_NAME_, done);
});
it('Rejects on invalid response 5', done => {
testInvalidResponse(INVALID_GET_RESPONSE_INVALID_STATE_, done);
});
it('Rejects on invalid response 6', done => {
testInvalidResponse(INVALID_GET_RESPONSE_INSTALLABLE_, done);
});
it('Rejects on mismatched app name', done => {
testInvalidResponse(INVALID_GET_RESPONSE_WRONG_APP_NAME_, done);
});
it('Rejects on error response', done => {
setMockXhrErrorResponse();
expectGetAppInfoFails(done);
});
it('Rejects on send rejection', done => {
setMockXhrReject();
expectGetAppInfoFails(done);
});
it('Rejects with AppInfoNotFoundError', done => {
setMockXhrNotFoundResponse();
client.getAppInfo('YouTube').then(
_ => {
fail('getAppInfo unexpectedly succeeded.');
},
e => {
expect(e instanceof DialClient.AppInfoNotFoundError).toBe(true);
expectMockSendGet();
done();
});
});
});
});