// Copyright 2014 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.

// Browser tests targeted at the RenderView that run in browser context.
// Note that these tests rely on single-process mode, and hence may be
// disabled in some configurations (check gyp files).

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_view.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "content/shell/common/shell_content_client.h"
#include "content/shell/renderer/shell_content_renderer_client.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/failing_http_transaction_factory.h"
#include "net/http/http_cache.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebURLError.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebFrame.h"

namespace content {

namespace {

class TestShellContentRendererClient : public ShellContentRendererClient {
 public:
  TestShellContentRendererClient()
      : latest_error_valid_(false),
        latest_error_reason_(0),
        latest_error_stale_copy_in_cache_(false) {}

  virtual void GetNavigationErrorStrings(
      content::RenderView* render_view,
      blink::WebFrame* frame,
      const blink::WebURLRequest& failed_request,
      const blink::WebURLError& error,
      std::string* error_html,
      base::string16* error_description) OVERRIDE {
    if (error_html)
      *error_html = "A suffusion of yellow.";
    latest_error_valid_ = true;
    latest_error_reason_ = error.reason;
    latest_error_stale_copy_in_cache_ = error.staleCopyInCache;
  }

  bool GetLatestError(int* error_code, bool* stale_cache_entry_present) {
    if (latest_error_valid_) {
      *error_code = latest_error_reason_;
      *stale_cache_entry_present = latest_error_stale_copy_in_cache_;
    }
    return latest_error_valid_;
  }

 private:
  bool latest_error_valid_;
  int latest_error_reason_;
  bool latest_error_stale_copy_in_cache_;
};

// Must be called on IO thread.
void InterceptNetworkTransactions(net::URLRequestContextGetter* getter,
                                  net::Error error) {
  DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO));
  net::HttpCache* cache(
      getter->GetURLRequestContext()->http_transaction_factory()->GetCache());
  DCHECK(cache);
  scoped_ptr<net::FailingHttpTransactionFactory> factory(
      new net::FailingHttpTransactionFactory(cache->GetSession(), error));
  // Throw away old version; since this is a browser test, there is no
  // need to restore the old state.
  cache->SetHttpNetworkTransactionFactoryForTesting(
      factory.PassAs<net::HttpTransactionFactory>());
}

void CallOnUIThreadValidatingReturn(const base::Closure& callback,
                                    int rv) {
  DCHECK_EQ(net::OK, rv);
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE, callback);
}

// Must be called on IO thread.  The callback will be called on
// completion of cache clearing on the UI thread.
void BackendClearCache(scoped_ptr<disk_cache::Backend*> backend,
                       const base::Closure& callback,
                       int rv) {
  DCHECK(*backend);
  DCHECK_EQ(net::OK, rv);
  (*backend)->DoomAllEntries(
      base::Bind(&CallOnUIThreadValidatingReturn, callback));
}

// Must be called on IO thread.  The callback will be called on
// completion of cache clearing on the UI thread.
void ClearCache(net::URLRequestContextGetter* getter,
                const base::Closure& callback) {
  DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO));
  net::HttpCache* cache(
      getter->GetURLRequestContext()->http_transaction_factory()->GetCache());
  DCHECK(cache);
  scoped_ptr<disk_cache::Backend*> backend(new disk_cache::Backend*);
  *backend = NULL;
  disk_cache::Backend** backend_ptr = backend.get();

  net::CompletionCallback backend_callback(
      base::Bind(&BackendClearCache, base::Passed(backend.Pass()), callback));

  // backend_ptr is valid until all copies of backend_callback go out
  // of scope.
  if (net::OK == cache->GetBackend(backend_ptr, backend_callback)) {
    // The call completed synchronously, so GetBackend didn't run the callback.
    backend_callback.Run(net::OK);
  }
}

}  // namespace

class RenderViewBrowserTest : public ContentBrowserTest {
 public:
  RenderViewBrowserTest() {}

  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    // This method is needed to allow interaction with in-process renderer
    // and use of a test ContentRendererClient.
    command_line->AppendSwitch(switches::kSingleProcess);
  }

  virtual void SetUpOnMainThread() OVERRIDE {
    // Override setting of renderer client.
    renderer_client_ = new TestShellContentRendererClient();
    // Explicitly leaks ownership; this object will remain alive
    // until process death.  We don't deleted the returned value,
    // since some contexts set the pointer to a non-heap address.
    SetRendererClientForTesting(renderer_client_);
  }

  // Navigates to the given URL and waits for |num_navigations| to occur, and
  // the title to change to |expected_title|.
  void NavigateToURLAndWaitForTitle(const GURL& url,
                                    const std::string& expected_title,
                                    int num_navigations) {
    content::TitleWatcher title_watcher(
        shell()->web_contents(), base::ASCIIToUTF16(expected_title));

    content::NavigateToURLBlockUntilNavigationsComplete(
        shell(), url, num_navigations);

    EXPECT_EQ(base::ASCIIToUTF16(expected_title),
              title_watcher.WaitAndGetTitle());
  }

  // Returns true if there is a valid error stored; in this case
  // |*error_code| and |*stale_cache_entry_present| will be updated
  // appropriately.
  // Must be called after the renderer thread is created.
  bool GetLatestErrorFromRendererClient(
      int* error_code, bool* stale_cache_entry_present) {
    bool result = false;

    PostTaskToInProcessRendererAndWait(
        base::Bind(&RenderViewBrowserTest::GetLatestErrorFromRendererClient0,
                   renderer_client_, &result, error_code,
                   stale_cache_entry_present));
    return result;
  }

 private:
  // Must be run on renderer thread.
  static void GetLatestErrorFromRendererClient0(
      TestShellContentRendererClient* renderer_client,
      bool* result, int* error_code, bool* stale_cache_entry_present) {
    *result = renderer_client->GetLatestError(
        error_code, stale_cache_entry_present);
  }

  TestShellContentRendererClient* renderer_client_;
};

IN_PROC_BROWSER_TEST_F(RenderViewBrowserTest, ConfirmCacheInformationPlumbed) {
  ASSERT_TRUE(test_server()->Start());

  // Load URL with "nocache" set, to create stale cache.
  GURL test_url(test_server()->GetURL("files/nocache.html"));
  NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1);

  // Reload same URL after forcing an error from the the network layer;
  // confirm that the error page is told the cached copy exists.
  int renderer_id =
      shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
      ShellContentBrowserClient::Get()->browser_context()->
          GetRequestContextForRenderProcess(renderer_id);
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&InterceptNetworkTransactions, url_request_context_getter,
                 net::ERR_FAILED));

  // An error results in one completed navigation.
  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
  int error_code = net::OK;
  bool stale_cache_entry_present = false;
  ASSERT_TRUE(GetLatestErrorFromRendererClient(
      &error_code, &stale_cache_entry_present));
  EXPECT_EQ(net::ERR_FAILED, error_code);
  EXPECT_TRUE(stale_cache_entry_present);

  // Clear the cache and repeat; confirm lack of entry in cache reported.
  scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&ClearCache, url_request_context_getter,
                 runner->QuitClosure()));
  runner->Run();

  content::NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);

  error_code = net::OK;
  stale_cache_entry_present = true;
  ASSERT_TRUE(GetLatestErrorFromRendererClient(
      &error_code, &stale_cache_entry_present));
  EXPECT_EQ(net::ERR_FAILED, error_code);
  EXPECT_FALSE(stale_cache_entry_present);
}

}  // namespace content
