// Copyright 2018 The Cobalt Authors. 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.

#include <string>

#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/platform_thread.h"
#include "cobalt/bindings/testing/utils.h"
#include "cobalt/css_parser/parser.h"
#include "cobalt/cssom/viewport_size.h"
#include "cobalt/dom/local_storage_database.h"
#include "cobalt/dom/testing/gtest_workarounds.h"
#include "cobalt/dom/window.h"
#include "cobalt/dom_parser/parser.h"
#include "cobalt/loader/fetcher_factory.h"
#include "cobalt/loader/loader_factory.h"
#include "cobalt/media_session/media_session.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/script/source_code.h"
#include "starboard/window.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using cobalt::cssom::ViewportSize;
using testing::InSequence;
using testing::Mock;

namespace cobalt {
namespace dom {

class MockErrorCallback : public base::Callback<void(const std::string&)> {
 public:
  MOCK_METHOD1(Run, void(const std::string&));
};

class OnScreenKeyboardMockBridge : public OnScreenKeyboardBridge {
 public:
  void Show(const char* input_text, int ticket) override {
    ShowMock(input_text);
    last_ticket_ = ticket;
    shown_ = true;
    script::Handle<script::Promise<void>> promise =
        LookupPromiseForShowTicket(last_ticket_);
    EXPECT_TRUE(promise->State() == cobalt::script::PromiseState::kPending);
    DCHECK(window_);
    window_->on_screen_keyboard()->DispatchShowEvent(last_ticket_);
    EXPECT_TRUE(promise->State() == cobalt::script::PromiseState::kFulfilled);
    last_ticket_ = -1;
  }

  void Hide(int ticket) override {
    HideMock();
    last_ticket_ = ticket;
    shown_ = false;

    script::Handle<script::Promise<void>> promise =
        LookupPromiseForHideTicket(last_ticket_);
    EXPECT_TRUE(promise->State() == cobalt::script::PromiseState::kPending);
    DCHECK(window_);
    window_->on_screen_keyboard()->DispatchHideEvent(last_ticket_);
    EXPECT_TRUE(promise->State() == cobalt::script::PromiseState::kFulfilled);
    last_ticket_ = -1;
  }

  void Focus(int ticket) override {
    FocusMock();
    last_ticket_ = ticket;
    script::Handle<script::Promise<void>> promise =
        LookupPromiseForFocusTicket(last_ticket_);
    EXPECT_TRUE(promise->State() == cobalt::script::PromiseState::kPending);
    DCHECK(window_);
    window_->on_screen_keyboard()->DispatchFocusEvent(last_ticket_);
    EXPECT_TRUE(promise->State() == cobalt::script::PromiseState::kFulfilled);
    last_ticket_ = -1;
  }

  void Blur(int ticket) override {
    BlurMock();
    last_ticket_ = ticket;
    script::Handle<script::Promise<void>> promise =
        LookupPromiseForBlurTicket(last_ticket_);
    EXPECT_TRUE(promise->State() == cobalt::script::PromiseState::kPending);
    DCHECK(window_);
    window_->on_screen_keyboard()->DispatchBlurEvent(last_ticket_);
    EXPECT_TRUE(promise->State() == cobalt::script::PromiseState::kFulfilled);
    last_ticket_ = -1;
  }

  bool IsShown() const override { return shown_; }

  scoped_refptr<DOMRect> BoundingRect() const override {
    return BoundingRectMock();
  }

  bool IsValidTicket(int ticket) const override {
    // The mock bridge will always dispatch events immediately once the
    // show/hide/focus/blur function has been called, meaning we will never need
    // to check the validity of a ticket that was not the last one generated.
    // This method will always return false when called outside one of the
    // show/hide/focus/blur methods.
    return ticket != -1 && ticket == last_ticket_;
  }

  void SetKeepFocus(bool keep_focus) override { SetKeepFocusMock(keep_focus); }

  MOCK_METHOD1(ShowMock, void(std::string));
  MOCK_METHOD0(HideMock, void());
  MOCK_METHOD0(BlurMock, void());
  MOCK_METHOD0(FocusMock, void());
  MOCK_CONST_METHOD0(BoundingRectMock, scoped_refptr<DOMRect>());
  MOCK_METHOD1(SetKeepFocusMock, void(bool));

  // We shortcut the event dispatching and handling for tests.
  dom::Window* window_;

 private:
  // OnScreenKeyboardMockBridge needs to be friends with dom::OnScreenKeyboard
  // to implement these functions.
  script::Handle<script::Promise<void>> LookupPromiseForShowTicket(int ticket) {
    DCHECK(window_);
    const auto& map =
        window_->on_screen_keyboard()->ticket_to_show_promise_map_;
    auto it = map.find(ticket);
    DCHECK(it != map.end());
    return script::Handle<script::Promise<void>>(*it->second);
  }

  script::Handle<script::Promise<void>> LookupPromiseForHideTicket(int ticket) {
    DCHECK(window_);
    const auto& map =
        window_->on_screen_keyboard()->ticket_to_hide_promise_map_;
    auto it = map.find(ticket);
    DCHECK(it != map.end());
    return script::Handle<script::Promise<void>>(*it->second);
  }

  script::Handle<script::Promise<void>> LookupPromiseForFocusTicket(
      int ticket) {
    DCHECK(window_);
    const auto& map =
        window_->on_screen_keyboard()->ticket_to_focus_promise_map_;
    auto it = map.find(ticket);
    DCHECK(it != map.end());
    return script::Handle<script::Promise<void>>(*it->second);
  }

  script::Handle<script::Promise<void>> LookupPromiseForBlurTicket(int ticket) {
    DCHECK(window_);
    const auto& map =
        window_->on_screen_keyboard()->ticket_to_blur_promise_map_;
    auto it = map.find(ticket);
    DCHECK(it != map.end());
    return script::Handle<script::Promise<void>>(*it->second);
  }

  bool shown_ = false;
  int last_ticket_ = -1;
};

namespace {

class OnScreenKeyboardTest : public ::testing::Test {
 public:
  OnScreenKeyboardTest()
      : environment_settings_(new script::EnvironmentSettings),
        message_loop_(MessageLoop::TYPE_DEFAULT),
        css_parser_(css_parser::Parser::Create()),
        dom_parser_(new dom_parser::Parser(mock_error_callback_)),
        fetcher_factory_(new loader::FetcherFactory(NULL)),
        loader_factory_(new loader::LoaderFactory(
            fetcher_factory_.get(), NULL, base::kThreadPriority_Default)),
        local_storage_database_(NULL),
        url_("about:blank"),
        engine_(script::JavaScriptEngine::CreateEngine()),
        global_environment_(engine_->CreateGlobalEnvironment()),
        on_screen_keyboard_bridge_(new OnScreenKeyboardMockBridge()),
        window_(new Window(
            ViewportSize(1920, 1080), 1.f, base::kApplicationStateStarted,
            css_parser_.get(), dom_parser_.get(), fetcher_factory_.get(),
            loader_factory_.get(), NULL, NULL, NULL, NULL, NULL, NULL,
            &local_storage_database_, NULL, NULL, NULL, NULL,
            global_environment_
                ->script_value_factory() /* script_value_factory */,
            NULL, NULL, url_, "", "en-US", "en",
            base::Callback<void(const GURL&)>(),
            base::Bind(&MockErrorCallback::Run,
                       base::Unretained(&mock_error_callback_)),
            NULL, network_bridge::PostSender(), csp::kCSPRequired,
            kCspEnforcementEnable, base::Closure() /* csp_policy_changed */,
            base::Closure() /* ran_animation_frame_callbacks */,
            dom::Window::CloseCallback() /* window_close */,
            base::Closure() /* window_minimize */,
            on_screen_keyboard_bridge_.get(), NULL, NULL,
            dom::Window::OnStartDispatchEventCallback(),
            dom::Window::OnStopDispatchEventCallback(),
            dom::ScreenshotManager::ProvideScreenshotFunctionCallback(),
            NULL)) {
    global_environment_->CreateGlobalObject(window_,
                                            environment_settings_.get());
    on_screen_keyboard_bridge_->window_ = window_;
  }

  ~OnScreenKeyboardTest() {
    global_environment_->SetReportEvalCallback(base::Closure());
    global_environment_->SetReportErrorCallback(
        script::GlobalEnvironment::ReportErrorCallback());
    window_->DispatchEvent(new dom::Event(base::Tokens::unload()));

    // TODO: figure out how to destruct OSK before global environment.
    window_->ReleaseOnScreenKeyboard();

    EXPECT_TRUE(Mock::VerifyAndClearExpectations(on_screen_keyboard_bridge()));

    on_screen_keyboard_bridge_.reset();
    window_ = nullptr;
    global_environment_ = nullptr;
  }

  bool EvaluateScript(const std::string& js_code, std::string* result);

  script::GlobalEnvironment* global_environment() const {
    return global_environment_.get();
  }

  OnScreenKeyboardMockBridge* on_screen_keyboard_bridge() const {
    return on_screen_keyboard_bridge_.get();
  }

  Window* window() const { return window_.get(); }

 private:
  const scoped_ptr<script::EnvironmentSettings> environment_settings_;
  MessageLoop message_loop_;
  MockErrorCallback mock_error_callback_;
  scoped_ptr<css_parser::Parser> css_parser_;
  scoped_ptr<dom_parser::Parser> dom_parser_;
  scoped_ptr<loader::FetcherFactory> fetcher_factory_;
  scoped_ptr<loader::LoaderFactory> loader_factory_;
  dom::LocalStorageDatabase local_storage_database_;
  GURL url_;

  scoped_ptr<script::JavaScriptEngine> engine_;
  scoped_refptr<script::GlobalEnvironment> global_environment_;
  scoped_ptr<OnScreenKeyboardMockBridge> on_screen_keyboard_bridge_;
  scoped_refptr<Window> window_;
};

// TODO: refactor this into reusable test utility.
bool OnScreenKeyboardTest::EvaluateScript(const std::string& js_code,
                                          std::string* result) {
  DCHECK(global_environment_);
  scoped_refptr<script::SourceCode> source_code =
      script::SourceCode::CreateSourceCode(
          js_code, base::SourceLocation(__FILE__, __LINE__, 1));

  global_environment_->EnableEval();
  global_environment_->SetReportEvalCallback(base::Closure());
  bool succeeded = global_environment_->EvaluateScript(source_code, result);
  return succeeded;
}

}  // namespace

#if SB_HAS(ON_SCREEN_KEYBOARD)
TEST_F(OnScreenKeyboardTest, ObjectExists) {
  std::string result;
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard;", &result));

  EXPECT_TRUE(bindings::testing::IsAcceptablePrototypeString("OnScreenKeyboard",
                                                             result));

  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.show;", &result));
  EXPECT_PRED_FORMAT2(::testing::IsSubstring, "function show()",
                      result.c_str());
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.hide;", &result));
  EXPECT_PRED_FORMAT2(::testing::IsSubstring, "function hide()",
                      result.c_str());
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.focus;", &result));
  EXPECT_PRED_FORMAT2(::testing::IsSubstring, "function focus()",
                      result.c_str());
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.blur;", &result));
  EXPECT_PRED_FORMAT2(::testing::IsSubstring, "function blur()",
                      result.c_str());

  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.keepFocus;", &result));
  EXPECT_STREQ("false", result.c_str());

  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.data;", &result));
  EXPECT_STREQ("", result.c_str());

  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.onshow;", &result));
  EXPECT_STREQ("null", result.c_str());
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.onhide;", &result));
  EXPECT_STREQ("null", result.c_str());
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.onblur;", &result));
  EXPECT_STREQ("null", result.c_str());
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.onfocus;", &result));
  EXPECT_STREQ("null", result.c_str());
}

TEST_F(OnScreenKeyboardTest, ShowAndHide) {
  // Not shown.
  std::string result;
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.shown;", &result));
  EXPECT_EQ("false", result);

  {
    InSequence seq;
    EXPECT_CALL(*(on_screen_keyboard_bridge()),
                ShowMock(window()->on_screen_keyboard()->data()));
    EXPECT_CALL(*(on_screen_keyboard_bridge()), HideMock());
  }
  // Show.
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.show();", &result));
  EXPECT_TRUE(
      bindings::testing::IsAcceptablePrototypeString("Object", result) ||
      bindings::testing::IsAcceptablePrototypeString("Promise", result));

  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.shown;", &result));
  EXPECT_EQ("true", result);

  // Hide.
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.hide();", &result));
  EXPECT_TRUE(
      bindings::testing::IsAcceptablePrototypeString("Object", result) ||
      bindings::testing::IsAcceptablePrototypeString("Promise", result));
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.shown;", &result));
  EXPECT_EQ("false", result);
}

TEST_F(OnScreenKeyboardTest, ShowAndHideMultipleTimes) {
  std::string result;
  {
    InSequence seq;
    EXPECT_CALL(*(on_screen_keyboard_bridge()),
                ShowMock(window()->on_screen_keyboard()->data()))
        .Times(3);
    EXPECT_CALL(*(on_screen_keyboard_bridge()), HideMock()).Times(3);
  }

  // Show multiple times.
  const char show_script[] = R"(
    window.onScreenKeyboard.show();
    window.onScreenKeyboard.show();
    window.onScreenKeyboard.show();
  )";
  EXPECT_TRUE(EvaluateScript(show_script, &result));
  EXPECT_TRUE(
      bindings::testing::IsAcceptablePrototypeString("Object", result) ||
      bindings::testing::IsAcceptablePrototypeString("Promise", result));

  // Hide multiple times.
  const char hide_script[] = R"(
    window.onScreenKeyboard.hide();
    window.onScreenKeyboard.hide();
    window.onScreenKeyboard.hide();
  )";
  EXPECT_TRUE(EvaluateScript(hide_script, &result));
  EXPECT_TRUE(
      bindings::testing::IsAcceptablePrototypeString("Object", result) ||
      bindings::testing::IsAcceptablePrototypeString("Promise", result));
}

TEST_F(OnScreenKeyboardTest, Data) {
  std::string result = "(empty)";
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.data;", &result));
  EXPECT_EQ("", result);

  std::string utf8_str = u8"z\u6c34\U0001d10b";
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.data = '" + utf8_str +
                                 "';"
                                 "window.onScreenKeyboard.data",
                             &result));
  EXPECT_EQ(utf8_str, result);
}

TEST_F(OnScreenKeyboardTest, FocusAndBlur) {
  std::string result;

  {
    InSequence seq;
    EXPECT_CALL(*(on_screen_keyboard_bridge()), FocusMock());
    EXPECT_CALL(*(on_screen_keyboard_bridge()), BlurMock());
  }
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.focus();", &result));
  EXPECT_TRUE(
      bindings::testing::IsAcceptablePrototypeString("Object", result) ||
      bindings::testing::IsAcceptablePrototypeString("Promise", result));
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.blur();", &result));
  EXPECT_TRUE(
      bindings::testing::IsAcceptablePrototypeString("Object", result) ||
      bindings::testing::IsAcceptablePrototypeString("Promise", result));
}
TEST_F(OnScreenKeyboardTest, FocusAndBlurMultipleTimes) {
  std::string result;
  {
    InSequence seq;
    EXPECT_CALL(*(on_screen_keyboard_bridge()), FocusMock()).Times(3);
    EXPECT_CALL(*(on_screen_keyboard_bridge()), BlurMock()).Times(3);
  }

  const char focus_script[] = R"(
    window.onScreenKeyboard.focus();
    window.onScreenKeyboard.focus();
    window.onScreenKeyboard.focus();
  )";
  EXPECT_TRUE(EvaluateScript(focus_script, &result));
  EXPECT_TRUE(
      bindings::testing::IsAcceptablePrototypeString("Object", result) ||
      bindings::testing::IsAcceptablePrototypeString("Promise", result));
  const char blur_script[] = R"(
    window.onScreenKeyboard.blur();
    window.onScreenKeyboard.blur();
    window.onScreenKeyboard.blur();
  )";
  EXPECT_TRUE(EvaluateScript(blur_script, &result));
  EXPECT_TRUE(
      bindings::testing::IsAcceptablePrototypeString("Object", result) ||
      bindings::testing::IsAcceptablePrototypeString("Promise", result));
}

TEST_F(OnScreenKeyboardTest, ShowEventAttribute) {
  EXPECT_CALL(*(on_screen_keyboard_bridge()),
              ShowMock(window()->on_screen_keyboard()->data()))
      .Times(3);
  const char let_script[] = R"(
    let promise;
    let logString;
  )";
  EXPECT_TRUE(EvaluateScript(let_script, NULL));
  const char event_script[] = R"(
    logString = '(empty)';
    window.onScreenKeyboard.onshow = function() {
      logString = 'show';
    };
    promise = window.onScreenKeyboard.show();
    logString;
  )";
  for (int i = 0; i < 3; ++i) {
    std::string result;
    EXPECT_TRUE(EvaluateScript(event_script, &result));
    EXPECT_EQ("show", result);
  }
}

TEST_F(OnScreenKeyboardTest, ShowEventListeners) {
  std::string result;
  EXPECT_CALL(*(on_screen_keyboard_bridge()),
              ShowMock(window()->on_screen_keyboard()->data()));
  const char script[] = R"(
    let logString1 = '(empty)';
    let logString2 = '(empty)';
    window.onScreenKeyboard.addEventListener('show',
      function() {
        logString1 = 'show1';
      });
    window.onScreenKeyboard.addEventListener('show',
      function() {
        logString2 = 'show2';
      });
    let promise = window.onScreenKeyboard.show();
    logString1;
  )";
  EXPECT_TRUE(EvaluateScript(script, &result));
  EXPECT_EQ("show1", result);
  EXPECT_TRUE(EvaluateScript("logString2", &result));
  EXPECT_EQ(result, "show2");
}

TEST_F(OnScreenKeyboardTest, HideEventAttribute) {
  EXPECT_CALL(*(on_screen_keyboard_bridge()), HideMock()).Times(3);
  const char let_script[] = R"(
    let promise;
    let logString;
  )";
  EXPECT_TRUE(EvaluateScript(let_script, NULL));
  const char event_script[] = R"(
    logString = '(empty)';
    window.onScreenKeyboard.onhide = function() {
      logString = 'hide';
    };
    promise = window.onScreenKeyboard.hide();
    logString;
  )";
  for (int i = 0; i < 3; ++i) {
    std::string result;
    EXPECT_TRUE(EvaluateScript(event_script, &result));
    EXPECT_EQ("hide", result);
  }
}

TEST_F(OnScreenKeyboardTest, HideEventListeners) {
  std::string result;
  EXPECT_CALL(*(on_screen_keyboard_bridge()), HideMock());
  const char script[] = R"(
    let logString1 = '(empty)';
    let logString2 = '(empty)';
    window.onScreenKeyboard.addEventListener('hide',
      function() {
        logString1 = 'hide1';
      });
    window.onScreenKeyboard.addEventListener('hide',
      function() {
        logString2 = 'hide2';
      });
    let promise = window.onScreenKeyboard.hide();
    logString1;
  )";
  EXPECT_TRUE(EvaluateScript(script, &result));
  EXPECT_EQ("hide1", result);
  EXPECT_TRUE(EvaluateScript("logString2", &result));
  EXPECT_EQ(result, "hide2");
}

TEST_F(OnScreenKeyboardTest, FocusEventAttribute) {
  EXPECT_CALL(*(on_screen_keyboard_bridge()), FocusMock()).Times(3);
  const char let_script[] = R"(
    let promise;
    let logString;
  )";
  EXPECT_TRUE(EvaluateScript(let_script, NULL));
  const char event_script[] = R"(
    logString = '(empty)';
    window.onScreenKeyboard.onfocus = function() {
      logString = 'focus';
    };
    promise = window.onScreenKeyboard.focus();
    logString;
  )";
  for (int i = 0; i < 3; ++i) {
    std::string result;
    EXPECT_TRUE(EvaluateScript(event_script, &result));
    EXPECT_EQ("focus", result);
  }
}

TEST_F(OnScreenKeyboardTest, FocusEventListeners) {
  std::string result;
  EXPECT_CALL(*(on_screen_keyboard_bridge()), FocusMock());
  const char script[] = R"(
    let logString1 = '(empty)';
    let logString2 = '(empty)';
    window.onScreenKeyboard.addEventListener('focus',
      function() {
        logString1 = 'focus1';
      });
    window.onScreenKeyboard.addEventListener('focus',
      function() {
        logString2 = 'focus2';
      });
    let promise = window.onScreenKeyboard.focus();
    logString1;
  )";
  EXPECT_TRUE(EvaluateScript(script, &result));
  EXPECT_EQ("focus1", result);
  EXPECT_TRUE(EvaluateScript("logString2", &result));
  EXPECT_EQ("focus2", result);
}

TEST_F(OnScreenKeyboardTest, BlurEventAttribute) {
  EXPECT_CALL(*(on_screen_keyboard_bridge()), BlurMock()).Times(3);
  const char let_script[] = R"(
    let promise;
    let logString;
  )";
  EXPECT_TRUE(EvaluateScript(let_script, NULL));
  const char event_script[] = R"(
    logString = '(empty)';
    window.onScreenKeyboard.onblur = function() {
      logString = 'blur';
    };
    promise = window.onScreenKeyboard.blur();
    logString;
  )";
  for (int i = 0; i < 3; ++i) {
    std::string result;
    EXPECT_TRUE(EvaluateScript(event_script, &result));
    EXPECT_EQ("blur", result);
  }
}

TEST_F(OnScreenKeyboardTest, BlurEventListeners) {
  std::string result;
  EXPECT_CALL(*(on_screen_keyboard_bridge()), BlurMock());
  const char script[] = R"(
    let logString1 = '(empty)';
    let logString2 = '(empty)';
    window.onScreenKeyboard.addEventListener('blur',
      function() {
        logString1 = 'blur1';
      });
    window.onScreenKeyboard.addEventListener('blur',
      function() {
        logString2 = 'blur2';
      });
    let promise = window.onScreenKeyboard.blur();
    logString1;
  )";
  EXPECT_TRUE(EvaluateScript(script, &result));
  EXPECT_EQ("blur1", result);
  EXPECT_TRUE(EvaluateScript("logString2", &result));
  EXPECT_EQ(result, "blur2");
}

TEST_F(OnScreenKeyboardTest, BoundingRect) {
  std::string result;
  EXPECT_CALL(*(on_screen_keyboard_bridge()), BoundingRectMock())
      .WillOnce(testing::Return(nullptr));
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.boundingRect;", &result));
  EXPECT_EQ("null", result);
}

TEST_F(OnScreenKeyboardTest, KeepFocus) {
  std::string result;
  {
    InSequence seq;
    EXPECT_CALL(*(on_screen_keyboard_bridge()), SetKeepFocusMock(true));
    EXPECT_CALL(*(on_screen_keyboard_bridge()), SetKeepFocusMock(false));
    EXPECT_CALL(*(on_screen_keyboard_bridge()), SetKeepFocusMock(true));
  }

  // Check initialization.
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard.keepFocus;", &result));
  EXPECT_EQ("false", result);

  const char script[] = R"(
    window.onScreenKeyboard.keepFocus = true;
    window.onScreenKeyboard.keepFocus = false;
    window.onScreenKeyboard.keepFocus = true;
  )";
  EXPECT_TRUE(EvaluateScript(script, NULL));
}
#else   // SB_HAS(ON_SCREEN_KEYBOARD)
TEST_F(OnScreenKeyboardTest, ObjectDoesntExist) {
  std::string result;

  EXPECT_TRUE(
      EvaluateScript("window.hasOwnProperty('onScreenKeyboard');", &result));
  EXPECT_EQ("false", result);
  EXPECT_TRUE(EvaluateScript("window.onScreenKeyboard;", &result));
  EXPECT_FALSE(bindings::testing::IsAcceptablePrototypeString(
      "OnScreenKeyboard", result));
  EXPECT_TRUE(EvaluateScript("typeof window.onScreenKeyboard === 'undefined';",
                             &result));
  EXPECT_EQ("true", result);

  // We should be able to assign anything we like to window.onScreenKeyboard.
  const char number_script[] = R"(
    window.onScreenKeyboard = 42;
    window.onScreenKeyboard;
  )";
  EXPECT_TRUE(EvaluateScript(number_script, &result));
  EXPECT_EQ("42", result);

  const char object_script[] = R"(
    window.onScreenKeyboard = {foo: 'bar'};
    window.onScreenKeyboard.hasOwnProperty('foo');
  )";
  EXPECT_TRUE(EvaluateScript(object_script, &result));
  EXPECT_EQ("true", result);
}
#endif  // SB_HAS(ON_SCREEN_KEYBOARD)

}  // namespace dom
}  // namespace cobalt
