<!DOCTYPE html>
<!--
Copyright 2011 Software Freedom Conservancy. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
  <title>http_test.html</title>
  <script src="../test_bootstrap.js"></script>
  <script>
    goog.require('bot.ErrorCode');
    goog.require('goog.Uri');
    goog.require('goog.json');
    goog.require('goog.testing.MockControl');
    goog.require('goog.testing.jsunit');
    goog.require('webdriver.Command');
    goog.require('webdriver.http.Client');
    goog.require('webdriver.http.Executor');
    goog.require('webdriver.promise');
    goog.require('webdriver.test.testutil');
  </script>
</head>
<body>
<script>
  // Alias for readability.
  var callbackHelper = webdriver.test.testutil.callbackHelper;

  var control = new goog.testing.MockControl();
  var mockClient, executor, onCallback, onErrback;

  function setUp() {
    mockClient = control.createStrictMock(webdriver.http.Client);

    executor = new webdriver.http.Executor(mockClient);
  }

  function tearDown() {
    control.$tearDown();
  }

  function assertSuccess() {
    onErrback.assertNotCalled('Did not expect errback');
    onCallback.assertCalled('Expected callback');
  }

  function assertFailure() {
    onCallback.assertNotCalled('Did not expect callback');
    onErrback.assertCalled('Expected errback');
  }

  function headersToString(headers) {
    var str = [];
    for (var key in headers) {
      str.push(key + ': ' + headers[key]);
    }
    return str.join('\n');
  }

  function expectRequest(method, path, data, headers) {
    var description = method + ' ' + path + '\n' + headersToString(headers) +
                      '\n' + goog.json.serialize(data);

    return mockClient.send(new goog.testing.mockmatchers.ArgumentMatcher(
        function(request) {
          assertEquals('wrong method', method, request.method);
          assertEquals('wrong path', path + '', request.path);
          webdriver.test.testutil.assertObjectEquals(data, request.data);
          assertNull(
              'Wrong headers for request:\n' + description +
              '\n    Actual headers were:\n' + headersToString(request.headers),
              goog.testing.asserts.findDifferences(headers, request.headers));
          return true;
        }, description),
        goog.testing.mockmatchers.isFunction);
  }

  function response(status, headers, body) {
    return new webdriver.http.Response(status, headers, body);
  }

  function respondsWith(error, opt_response) {
    return function(request, callback) {
      callback(error, opt_response);
    };
  }

///////////////////////////////////////////////////////////////////////////////
//
//  Tests
//
///////////////////////////////////////////////////////////////////////////////

  function testBuildPath() {
    var parameters = {'sessionId':'foo', 'url':'http://www.google.com'};
    var finalPath = webdriver.http.Executor.buildPath_(
        '/session/:sessionId/url', parameters);
    assertEquals('/session/foo/url', finalPath);
    webdriver.test.testutil.assertObjectEquals({'url':'http://www.google.com'},
        parameters);
  }

  function testBuildPath_withWebElement() {
    var parameters = {'sessionId':'foo', 'id': {}};
    parameters['id']['ELEMENT'] = 'bar';

    var finalPath = webdriver.http.Executor.buildPath_(
        '/session/:sessionId/element/:id/click', parameters);
    assertEquals('/session/foo/element/bar/click', finalPath);
    webdriver.test.testutil.assertObjectEquals({}, parameters);
  }

  function testBuildPath_throwsIfMissingParameter() {
    assertThrows(goog.partial(webdriver.http.Executor.buildPath_,
        '/session/:sessionId', {}));

    assertThrows(goog.partial(webdriver.http.Executor.buildPath_,
        '/session/:sessionId/element/:id', {'sessionId': 'foo'}));
  }

  function testBuildPath_doesNotMatchOnSegmentsThatDoNotStartWithColon() {
    assertEquals('/session/foo:bar/baz',
        webdriver.http.Executor.buildPath_('/session/foo:bar/baz', {}));
  }

  function testExecute_rejectsUnrecognisedCommands() {
    assertThrows(goog.bind(executor.execute, executor,
        new webdriver.Command('fake-command-name'), goog.nullFunction));
  }

  /**
   * @param {!webdriver.Command} command The command to send.
   * @param {!Function=} opt_onSuccess The function to check the response with.
   */
  function assertSendsSuccessfully(command, opt_onSuccess) {
    var callback;
    executor.execute(command, callback = callbackHelper(function(e, response) {
      assertNull(e);
      assertNotNullNorUndefined(response);
      if (opt_onSuccess) {
        opt_onSuccess(response);
      }
    }));
    callback.assertCalled();
    control.$verifyAll();
  }

  /**
   * @param {!webdriver.Command} command The command to send.
   * @param {!Function=} opt_onError The function to check the error with.
   */
  function assertFailsToSend(command, opt_onError) {
    var callback;
    executor.execute(command, callback = callbackHelper(function(e, response) {
      assertNotNullNorUndefined(e);
      assertUndefined(response);
      if (opt_onError) {
        opt_onError(e);
      }
    }));
    callback.assertCalled();
    control.$verifyAll();
  }

  function testExecute_clientFailsToSendRequest() {
    var error = new Error('boom');
    expectRequest('POST', '/session', {}, {
      'Accept': 'application/json; charset=utf-8'
    }).
    $does(respondsWith(error));
    control.$replayAll();

    assertFailsToSend(new webdriver.Command(webdriver.CommandName.NEW_SESSION),
        function(e) {
          assertEquals(error, e);
        });
  }

  function testExecute_commandWithNoUrlParameters() {
    expectRequest('POST', '/session', {}, {
      'Accept': 'application/json; charset=utf-8'
    }).
    $does(respondsWith(null, response(200, {}, '')));
    control.$replayAll();

    assertSendsSuccessfully(
        new webdriver.Command(webdriver.CommandName.NEW_SESSION));
  }

  function testExecute_rejectsCommandsMissingUrlParameters() {
    var command =
        new webdriver.Command(webdriver.CommandName.FIND_CHILD_ELEMENT).
            setParameter('sessionId', 's123').
            // Let this be missing: setParameter('id', {'ELEMENT': 'e456'}).
            setParameter('using', 'id').
            setParameter('value', 'foo');

    control.$replayAll();
    assertThrows(goog.bind(executor.execute, executor, command));
    control.$verifyAll();
  }

  function testExecute_replacesUrlParametersWithCommandParameters() {
    var command =
        new webdriver.Command(webdriver.CommandName.GET).
            setParameter('sessionId', 's123').
            setParameter('url', 'http://www.google.com');

    expectRequest('POST', '/session/s123/url',
        {'url': 'http://www.google.com'},
        {'Accept': 'application/json; charset=utf-8'}).
        $does(respondsWith(null, response(200, {}, '')));
    control.$replayAll();

    assertSendsSuccessfully(command);
  }

  function testExecute_returnsParsedJsonResponse() {
    var responseObj = {
      'status': bot.ErrorCode.SUCCESS,
      'value': 'http://www.google.com'
    };
    var command = new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL).
        setParameter('sessionId', 's123');

    expectRequest('GET', '/session/s123/url', {}, {
      'Accept': 'application/json; charset=utf-8'
    }).$does(respondsWith(null,
        response(200, {'Content-Type': 'application/json'},
            goog.json.serialize(responseObj))));
    control.$replayAll();

    assertSendsSuccessfully(command, function(response) {
      webdriver.test.testutil.assertObjectEquals(responseObj, response);
    });
  }

  function testExecute_returnsSuccessFor2xxWithBodyAsValueWhenNotJson() {
    var command = new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL).
        setParameter('sessionId', 's123');

    expectRequest('GET', '/session/s123/url', {}, {
      'Accept': 'application/json; charset=utf-8'
    }).$does(respondsWith(null,
        response(200, {}, 'hello, world\r\ngoodbye, world!')));
    control.$replayAll();

    assertSendsSuccessfully(command, function(response) {
      webdriver.test.testutil.assertObjectEquals({
        'status': bot.ErrorCode.SUCCESS,
        'value': 'hello, world\ngoodbye, world!'
      }, response);
    });
  }

  function testExecute_returnsSuccessFor2xxInvalidJsonBody() {
    var invalidJson = '[';
    expectRequest('POST', '/session', {}, {
      'Accept': 'application/json; charset=utf-8'
    }).
    $does(respondsWith(null, response(200, {
      'Content-Type': 'application/json'
    }, invalidJson)));
    control.$replayAll();

    assertSendsSuccessfully(
        new webdriver.Command(webdriver.CommandName.NEW_SESSION),
        function(response) {
          webdriver.test.testutil.assertObjectEquals({
            'status': bot.ErrorCode.SUCCESS,
            'value': invalidJson
          }, response);
        });
  }

  function testExecute_returnsUnknownCommandFor404WithBodyAsValueWhenNotJson() {
    var command = new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL).
        setParameter('sessionId', 's123');

    expectRequest('GET', '/session/s123/url', {}, {
      'Accept': 'application/json; charset=utf-8'
    }).$does(respondsWith(null,
        response(404, {}, 'hello, world\r\ngoodbye, world!')));
    control.$replayAll();

    assertSendsSuccessfully(command, function(response) {
      webdriver.test.testutil.assertObjectEquals({
        'status': bot.ErrorCode.UNKNOWN_COMMAND,
        'value': 'hello, world\ngoodbye, world!'
      }, response);
    });
  }

  function testExecute_returnsUnknownErrorForGenericErrorCodeWithBodyAsValueWhenNotJson() {
    var command = new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL).
        setParameter('sessionId', 's123');

    expectRequest('GET', '/session/s123/url', {}, {
      'Accept': 'application/json; charset=utf-8'
    }).$does(respondsWith(null,
        response(500, {}, 'hello, world\r\ngoodbye, world!')));
    control.$replayAll();

    assertSendsSuccessfully(command, function(response) {
      webdriver.test.testutil.assertObjectEquals({
        'status': bot.ErrorCode.UNKNOWN_ERROR,
        'value': 'hello, world\ngoodbye, world!'
      }, response);
    });
  }

  function testExecute_attemptsToParseBodyWhenNoContentTypeSpecified() {
    var responseObj = {
      'status': bot.ErrorCode.SUCCESS,
      'value': 'http://www.google.com'
    };
    var command = new webdriver.Command(webdriver.CommandName.GET_CURRENT_URL).
        setParameter('sessionId', 's123');

    expectRequest('GET', '/session/s123/url', {}, {
      'Accept': 'application/json; charset=utf-8'
    }).$does(respondsWith(null,
        response(200, {}, goog.json.serialize(responseObj))));
    control.$replayAll();

    assertSendsSuccessfully(command, function(response) {
      webdriver.test.testutil.assertObjectEquals(responseObj, response);
    });
  }

  function FakeXmlHttpRequest(headers, status, responseText) {
    return {
      getAllResponseHeaders: function() { return headers; },
      status: status,
      responseText: responseText
    };
  }

  function testXmlHttpRequestToHttpResponse_parseHeaders_windows() {
    var response = webdriver.http.Response.fromXmlHttpRequest(
        FakeXmlHttpRequest([
          'a:b',
          'c: d',
          'e :f',
          'g : h'
        ].join('\r\n'), 200, ''));
    assertEquals(200, response.status);
    assertEquals('', response.body);

    webdriver.test.testutil.assertObjectEquals({
      'a': 'b',
      'c': 'd',
      'e': 'f',
      'g': 'h'
    }, response.headers);
  }

  function testXmlHttpRequestToHttpResponse_parseHeaders_unix() {
    var response = webdriver.http.Response.fromXmlHttpRequest(
        FakeXmlHttpRequest([
          'a:b',
          'c: d',
          'e :f',
          'g : h'
        ].join('\n'), 200, ''));
    assertEquals(200, response.status);
    assertEquals('', response.body);

    webdriver.test.testutil.assertObjectEquals({
      'a': 'b',
      'c': 'd',
      'e': 'f',
      'g': 'h'
    }, response.headers);
  }

  function testXmlHttpRequestToHttpResponse_noHeaders() {
    var response = webdriver.http.Response.fromXmlHttpRequest(
        FakeXmlHttpRequest('', 200, ''));
    assertEquals(200, response.status);
    assertEquals('', response.body);
    webdriver.test.testutil.assertObjectEquals({}, response.headers);
  }

  function testXmlHttpRequestToHttpResponse_stripsNullCharactersFromBody() {
    var response = webdriver.http.Response.fromXmlHttpRequest(
        FakeXmlHttpRequest('', 200, '\x00\0foo\x00\x00bar\x00\0'));
    assertEquals(200, response.status);
    assertEquals('foobar', response.body);
    webdriver.test.testutil.assertObjectEquals({}, response.headers);
  }
</script>
</body>
</html>
