xhrstreamreader_test.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // Copyright 2015 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. goog.provide('goog.net.streams.XhrStreamReaderTest');
  15. goog.setTestOnly('goog.net.streams.XhrStreamReaderTest');
  16. goog.require('goog.net.ErrorCode');
  17. goog.require('goog.net.XmlHttp');
  18. goog.require('goog.net.streams.Base64PbStreamParser');
  19. goog.require('goog.net.streams.JsonStreamParser');
  20. goog.require('goog.net.streams.PbJsonStreamParser');
  21. goog.require('goog.net.streams.PbStreamParser');
  22. goog.require('goog.net.streams.XhrStreamReader');
  23. goog.require('goog.object');
  24. goog.require('goog.testing.asserts');
  25. goog.require('goog.testing.jsunit');
  26. goog.require('goog.testing.net.XhrIo');
  27. var Base64PbStreamParser =
  28. goog.module.get('goog.net.streams.Base64PbStreamParser');
  29. var PbJsonStreamParser = goog.module.get('goog.net.streams.PbJsonStreamParser');
  30. var xhrReader;
  31. var xhrIo;
  32. var Status = goog.net.streams.XhrStreamReader.Status;
  33. var ReadyState = goog.net.XmlHttp.ReadyState;
  34. var CONTENT_TYPE_HEADER = goog.net.XhrIo.CONTENT_TYPE_HEADER;
  35. var CONTENT_TRANSFER_ENCODING = goog.net.XhrIo.CONTENT_TRANSFER_ENCODING;
  36. function shouldRunTests() {
  37. return goog.net.streams.XhrStreamReader.isStreamingSupported();
  38. }
  39. function setUp() {
  40. xhrIo = new goog.testing.net.XhrIo();
  41. xhrReader = new goog.net.streams.XhrStreamReader(xhrIo);
  42. }
  43. function tearDown() {
  44. xhrIo = null;
  45. xhrReader = null;
  46. }
  47. function testGetParserByResponseHeader() {
  48. xhrIo.getStreamingResponseHeader = function() { return null; };
  49. assertNull(xhrReader.getParserByResponseHeader_());
  50. xhrIo.getStreamingResponseHeader = function() { return ''; };
  51. assertNull(xhrReader.getParserByResponseHeader_());
  52. xhrIo.getStreamingResponseHeader = function() { return 'xxxxx'; };
  53. assertNull(xhrReader.getParserByResponseHeader_());
  54. xhrIo.getStreamingResponseHeader = function(key) {
  55. if (key == CONTENT_TYPE_HEADER) return 'application/json';
  56. return null;
  57. };
  58. assertTrue(
  59. xhrReader.getParserByResponseHeader_() instanceof
  60. goog.net.streams.JsonStreamParser);
  61. xhrIo.getStreamingResponseHeader = function(key) {
  62. if (key == CONTENT_TYPE_HEADER) return 'application/json; charset=utf-8';
  63. return null;
  64. };
  65. assertTrue(
  66. xhrReader.getParserByResponseHeader_() instanceof
  67. goog.net.streams.JsonStreamParser);
  68. xhrIo.getStreamingResponseHeader = function(key) {
  69. if (key == CONTENT_TYPE_HEADER) return 'application/x-protobuf';
  70. return null;
  71. };
  72. assertTrue(
  73. xhrReader.getParserByResponseHeader_() instanceof
  74. goog.net.streams.PbStreamParser);
  75. xhrIo.getStreamingResponseHeader = function(key) {
  76. if (key == CONTENT_TYPE_HEADER) return 'application/x-protobuf';
  77. if (key == CONTENT_TRANSFER_ENCODING) return 'BASE64';
  78. return null;
  79. };
  80. assertTrue(
  81. xhrReader.getParserByResponseHeader_() instanceof Base64PbStreamParser);
  82. xhrIo.getStreamingResponseHeader = function(key) {
  83. if (key == CONTENT_TYPE_HEADER) return 'application/json+protobuf';
  84. return null;
  85. };
  86. assertTrue(
  87. xhrReader.getParserByResponseHeader_() instanceof PbJsonStreamParser);
  88. }
  89. function testNoData() {
  90. xhrReader.setDataHandler(function(messages) {
  91. fail('Received unexpected messages: ' + messages);
  92. });
  93. var streamStatus = [];
  94. var httpStatus = [];
  95. xhrReader.setStatusHandler(function() {
  96. streamStatus.push(xhrReader.getStatus());
  97. httpStatus.push(xhrIo.getStatus());
  98. });
  99. var headers = {'Content-Type': 'application/json'};
  100. xhrIo.send('/foo/bar');
  101. xhrIo.simulateResponse(goog.net.HttpStatus.OK, '', headers);
  102. assertElementsEquals([Status.NO_DATA], streamStatus);
  103. assertElementsEquals([goog.net.HttpStatus.OK], httpStatus);
  104. }
  105. function testRetrieveHttpStatusInStatusHandler() {
  106. var received = [];
  107. xhrReader.setDataHandler(function(messages) {
  108. received.push(messages);
  109. });
  110. var streamStatus = [];
  111. var httpStatus = [];
  112. xhrReader.setStatusHandler(function() {
  113. console.log('in setStatusHandler');
  114. streamStatus.push(xhrReader.getStatus());
  115. httpStatus.push(xhrIo.getStatus());
  116. });
  117. var headers = {'Content-Type': 'application/json'};
  118. xhrIo.send('/foo/bar');
  119. xhrIo.simulateResponse(goog.net.HttpStatus.OK, '[{"1" : "b"}]', headers);
  120. assertEquals(1, received.length);
  121. assertEquals(1, received[0].length);
  122. assertElementsEquals(['1'], goog.object.getKeys(received[0][0]));
  123. assertElementsEquals('b', received[0][0][1]);
  124. assertElementsEquals([Status.ACTIVE, Status.SUCCESS], streamStatus);
  125. assertElementsEquals(
  126. [goog.net.HttpStatus.OK, goog.net.HttpStatus.OK], httpStatus);
  127. }
  128. function testParsingSingleMessage() {
  129. var received = [];
  130. xhrReader.setDataHandler(function(messages) { received.push(messages); });
  131. var body = 'CgX__gABdw==';
  132. var headers = {
  133. 'Content-Type': 'application/x-protobuf',
  134. 'Content-Transfer-Encoding': 'BASE64'
  135. };
  136. xhrIo.send('/foo/bar');
  137. xhrIo.simulateResponse(goog.net.HttpStatus.OK, body, headers);
  138. assertEquals(1, received.length);
  139. assertEquals(1, received[0].length);
  140. assertElementsEquals(['1'], goog.object.getKeys(received[0][0]));
  141. assertElementsEquals([0xFF, 0xFE, 0x00, 0x01, 0x77], received[0][0][1]);
  142. }
  143. function testParsingMultipleMessages() {
  144. /**
  145. * Pass the following protobuf messages
  146. * 0x0a, 0x03, 0x61, 0x62, 0x63,
  147. * 0x0a, 0x03, 0x64, 0x65, 0x66,
  148. * 0x12, 0x03, 0x67, 0x68, 0x69,
  149. * 0x0a, 0x03, 0x6a, 0x6b, 0x6c,
  150. */
  151. var chunk1 = 'CgNh';
  152. var chunk2 = 'YmMKA';
  153. var chunk3 = '2RlZhIDZ2hpCg';
  154. var chunk4 = 'Nqa2w=';
  155. var received = [];
  156. xhrReader.setDataHandler(function(messages) { received.push(messages); });
  157. var headers = {
  158. 'Content-Type': 'application/x-protobuf',
  159. 'Content-Transfer-Encoding': 'BASE64'
  160. };
  161. xhrIo.send('/foo/bar');
  162. xhrIo.simulatePartialResponse(chunk1, headers);
  163. assertEquals(0, received.length);
  164. xhrIo.simulatePartialResponse(chunk2);
  165. assertEquals(1, received.length);
  166. assertEquals(1, received[0].length);
  167. assertElementsEquals(['1'], goog.object.getKeys(received[0][0]));
  168. assertElementsEquals([0x61, 0x62, 0x63], received[0][0][1]);
  169. received = [];
  170. xhrIo.simulatePartialResponse(chunk3);
  171. assertEquals(1, received.length);
  172. assertEquals(2, received[0].length);
  173. assertElementsEquals(['1'], goog.object.getKeys(received[0][0]));
  174. assertElementsEquals([0x64, 0x65, 0x66], received[0][0][1]);
  175. assertElementsEquals(['2'], goog.object.getKeys(received[0][1]));
  176. assertElementsEquals([0x67, 0x68, 0x69], received[0][1][2]);
  177. received = [];
  178. xhrIo.simulatePartialResponse(chunk4);
  179. assertEquals(1, received.length);
  180. assertEquals(1, received[0].length);
  181. assertElementsEquals(['1'], goog.object.getKeys(received[0][0]));
  182. assertElementsEquals([0x6a, 0x6b, 0x6c], received[0][0][1]);
  183. xhrIo.simulateReadyStateChange(ReadyState.COMPLETE);
  184. assertEquals(Status.SUCCESS, xhrReader.getStatus());
  185. }
  186. function testXhrTimeout() {
  187. xhrIo.send('/test', null, 'GET', null, null, 1000, false);
  188. xhrIo.simulatePartialResponse('', {'Content-Type': 'application/x-protobuf'});
  189. xhrIo.getLastErrorCode = function() { return goog.net.ErrorCode.TIMEOUT; };
  190. xhrIo.simulateReadyStateChange(ReadyState.COMPLETE);
  191. assertEquals(Status.TIMEOUT, xhrReader.getStatus());
  192. }
  193. // TODO: more mocked/networked tests, testing.xhrio not useful for streaming
  194. // states