web_view_inttest_base.mm 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright 2017 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.
  4. #import "ios/web_view/test/web_view_inttest_base.h"
  5. #import <ChromeWebView/ChromeWebView.h>
  6. #import <Foundation/Foundation.h>
  7. #include "base/base64.h"
  8. #include "base/bind.h"
  9. #import "base/memory/ptr_util.h"
  10. #include "base/strings/stringprintf.h"
  11. #import "ios/web/common/uikit_ui_util.h"
  12. #import "ios/web_view/test/web_view_test_util.h"
  13. #include "net/base/url_util.h"
  14. #include "net/test/embedded_test_server/embedded_test_server.h"
  15. #include "net/test/embedded_test_server/http_request.h"
  16. #include "net/test/embedded_test_server/http_response.h"
  17. #include "testing/gtest/include/gtest/gtest.h"
  18. #if !defined(__has_feature) || !__has_feature(objc_arc)
  19. #error "This file requires ARC support."
  20. #endif
  21. namespace {
  22. // Test server path which renders a basic html page.
  23. const char kPageHtmlPath[] = "/PageHtml?";
  24. // URL parameter for entire html. Value must be base64 encoded.
  25. // kPageHtmlBodyParamName and kPageHtmlTitleParamName are ignored when this is
  26. // given.
  27. const char kPageHtmlParamName[] = "html";
  28. // URL parameter for html body. Value must be base64 encoded.
  29. const char kPageHtmlBodyParamName[] = "body";
  30. // URL parameter for page title. Value must be base64 encoded.
  31. const char kPageHtmlTitleParamName[] = "title";
  32. // Generates html from title and body.
  33. std::string CreatePageHTML(const std::string& title, const std::string& body) {
  34. return base::StringPrintf(
  35. "<html><head><title>%s</title></head><body>%s</body></html>",
  36. title.c_str(), body.c_str());
  37. }
  38. // Returns true if |string| starts with |prefix|. String comparison is case
  39. // insensitive.
  40. bool StartsWith(std::string string, std::string prefix) {
  41. return base::StartsWith(string, prefix, base::CompareCase::SENSITIVE);
  42. }
  43. // Encodes the |string| for use as the value of a url parameter.
  44. std::string EncodeQueryParamValue(std::string string) {
  45. std::string encoded_string;
  46. base::Base64Encode(string, &encoded_string);
  47. return encoded_string;
  48. }
  49. // Decodes the |encoded_string|. Undoes the encoding performed by
  50. // |EncodeQueryParamValue|.
  51. std::string DecodeQueryParamValue(std::string encoded_string) {
  52. std::string decoded_string;
  53. base::Base64Decode(encoded_string, &decoded_string);
  54. return decoded_string;
  55. }
  56. // Maps test server requests to responses.
  57. std::unique_ptr<net::test_server::HttpResponse> TestRequestHandler(
  58. const net::test_server::HttpRequest& request) {
  59. if (StartsWith(request.relative_url, kPageHtmlPath)) {
  60. std::string title;
  61. std::string body;
  62. std::string html;
  63. GURL request_url = request.GetURL();
  64. std::string encoded_html;
  65. bool html_found = net::GetValueForKeyInQuery(
  66. request_url, kPageHtmlParamName, &encoded_html);
  67. if (html_found) {
  68. html = DecodeQueryParamValue(encoded_html);
  69. } else {
  70. std::string encoded_title;
  71. bool title_found = net::GetValueForKeyInQuery(
  72. request_url, kPageHtmlTitleParamName, &encoded_title);
  73. if (title_found) {
  74. title = DecodeQueryParamValue(encoded_title);
  75. }
  76. std::string encoded_body;
  77. bool body_found = net::GetValueForKeyInQuery(
  78. request_url, kPageHtmlBodyParamName, &encoded_body);
  79. if (body_found) {
  80. body = DecodeQueryParamValue(encoded_body);
  81. }
  82. html = CreatePageHTML(title, body);
  83. }
  84. auto http_response =
  85. std::make_unique<net::test_server::BasicHttpResponse>();
  86. http_response->set_content(html);
  87. return std::move(http_response);
  88. }
  89. return nullptr;
  90. }
  91. } // namespace
  92. namespace ios_web_view {
  93. WebViewInttestBase::WebViewInttestBase()
  94. : web_view_(test::CreateWebView()),
  95. test_server_(std::make_unique<net::EmbeddedTestServer>(
  96. net::test_server::EmbeddedTestServer::TYPE_HTTP)) {
  97. // The WKWebView must be present in the view hierarchy in order to prevent
  98. // WebKit optimizations which may pause internal parts of the web view
  99. // without notice. Work around this by adding the view directly.
  100. UIViewController* view_controller = [GetAnyKeyWindow() rootViewController];
  101. [view_controller.view addSubview:web_view_];
  102. test_server_->AddDefaultHandlers(FILE_PATH_LITERAL(base::FilePath()));
  103. test_server_->RegisterRequestHandler(
  104. base::BindRepeating(&TestRequestHandler));
  105. }
  106. WebViewInttestBase::~WebViewInttestBase() {
  107. [web_view_ removeFromSuperview];
  108. }
  109. GURL WebViewInttestBase::GetUrlForPageWithTitle(const std::string& title) {
  110. return GetUrlForPageWithTitleAndBody(title, std::string());
  111. }
  112. GURL WebViewInttestBase::GetUrlForPageWithHtmlBody(const std::string& html) {
  113. return GetUrlForPageWithTitleAndBody(std::string(), html);
  114. }
  115. GURL WebViewInttestBase::GetUrlForPageWithTitleAndBody(
  116. const std::string& title,
  117. const std::string& body) {
  118. GURL url = test_server_->GetURL(kPageHtmlPath);
  119. // Encode |title| and |body| in url query in order to build the server
  120. // response later in TestRequestHandler.
  121. std::string encoded_title = EncodeQueryParamValue(title);
  122. url = net::AppendQueryParameter(url, kPageHtmlTitleParamName, encoded_title);
  123. std::string encoded_body = EncodeQueryParamValue(body);
  124. url = net::AppendQueryParameter(url, kPageHtmlBodyParamName, encoded_body);
  125. return url;
  126. }
  127. GURL WebViewInttestBase::GetUrlForPageWithHtml(const std::string& html) {
  128. GURL url = test_server_->GetURL(kPageHtmlPath);
  129. // Encode |html| in url query in order to build the server
  130. // response later in TestRequestHandler.
  131. std::string encoded_html = EncodeQueryParamValue(html);
  132. url = net::AppendQueryParameter(url, kPageHtmlParamName, encoded_html);
  133. return url;
  134. }
  135. } // namespace ios_web_view