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

#include "content/public/browser/frame_service_base.h"

#include "base/bind.h"
#include "base/run_loop.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_renderer_host.h"
#include "content/test/echo.mojom.h"
#include "content/test/test_render_frame_host.h"
#include "url/gurl.h"

// Unit test for FrameServiceBase in content/public/browser.

namespace content {

namespace {

const char kFooOrigin[] = "https://foo.com";
const char kBarOrigin[] = "https://bar.com";

// Subclass of FrameServiceBase for test.
class EchoImpl final : public FrameServiceBase<mojom::Echo> {
 public:
  EchoImpl(RenderFrameHost* render_frame_host,
           mojo::InterfaceRequest<mojom::Echo> request,
           base::OnceClosure destruction_cb)
      : FrameServiceBase(render_frame_host, std::move(request)),
        destruction_cb_(std::move(destruction_cb)) {}
  ~EchoImpl() final { std::move(destruction_cb_).Run(); }

  // mojom::Echo implementation
  void EchoString(const std::string& input, EchoStringCallback callback) final {
    std::move(callback).Run(input);
  }

 private:
  base::OnceClosure destruction_cb_;
};

// Help functions to manipulate RenderFrameHosts.

// Simulates navigation and returns the final RenderFrameHost.
RenderFrameHost* SimulateNavigation(RenderFrameHost* rfh, const GURL& url) {
  auto navigation_simulator =
      NavigationSimulator::CreateRendererInitiated(url, rfh);
  navigation_simulator->Commit();
  return navigation_simulator->GetFinalRenderFrameHost();
}

RenderFrameHost* AddChildFrame(RenderFrameHost* rfh, const GURL& url) {
  RenderFrameHost* child_rfh = RenderFrameHostTester::For(rfh)->AppendChild("");
  RenderFrameHostTester::For(child_rfh)->InitializeRenderFrameIfNeeded();
  return SimulateNavigation(child_rfh, url);
}

void DetachFrame(RenderFrameHost* rfh) {
  RenderFrameHostTester::For(rfh)->Detach();
}

}  // namespace

class FrameServiceBaseTest : public RenderViewHostTestHarness {
 protected:
  void SetUp() final {
    RenderViewHostTestHarness::SetUp();
    Initialize();
  }

  void Initialize() {
    RenderFrameHost* main_rfh = web_contents()->GetMainFrame();
    RenderFrameHostTester::For(main_rfh)->InitializeRenderFrameIfNeeded();
    main_rfh_ = SimulateNavigation(main_rfh, GURL(kFooOrigin));
  }

  void CreateEchoImpl(RenderFrameHost* rfh) {
    DCHECK(!is_echo_impl_alive_);
    new EchoImpl(rfh, mojo::MakeRequest(&echo_ptr_),
                 base::BindOnce(&FrameServiceBaseTest::OnEchoImplDestructed,
                                base::Unretained(this)));
    is_echo_impl_alive_ = true;
  }

  void OnEchoImplDestructed() {
    DCHECK(is_echo_impl_alive_);
    is_echo_impl_alive_ = false;
  }

  void ResetConnection() {
    echo_ptr_.reset();
    base::RunLoop().RunUntilIdle();
  }

  RenderFrameHost* main_rfh_ = nullptr;
  mojom::EchoPtr echo_ptr_;
  bool is_echo_impl_alive_ = false;
};

TEST_F(FrameServiceBaseTest, ConnectionError) {
  CreateEchoImpl(main_rfh_);
  ResetConnection();
  EXPECT_FALSE(is_echo_impl_alive_);
}

TEST_F(FrameServiceBaseTest, RenderFrameDeleted) {
  // Needs to create a child frame so we can delete it using DetachFrame()
  // because it is not allowed to detach the main frame.
  RenderFrameHost* child_rfh = AddChildFrame(main_rfh_, GURL(kBarOrigin));
  CreateEchoImpl(child_rfh);
  DetachFrame(child_rfh);
  EXPECT_FALSE(is_echo_impl_alive_);
}

TEST_F(FrameServiceBaseTest, DidFinishNavigation) {
  CreateEchoImpl(main_rfh_);
  SimulateNavigation(main_rfh_, GURL(kBarOrigin));
  EXPECT_FALSE(is_echo_impl_alive_);
}

TEST_F(FrameServiceBaseTest, SameDocumentNavigation) {
  CreateEchoImpl(main_rfh_);

  // Must use the same origin to simulate same document navigation.
  auto navigation_simulator =
      NavigationSimulator::CreateRendererInitiated(GURL(kFooOrigin), main_rfh_);
  navigation_simulator->CommitSameDocument();
  DCHECK_EQ(main_rfh_, navigation_simulator->GetFinalRenderFrameHost());

  EXPECT_TRUE(is_echo_impl_alive_);
}

TEST_F(FrameServiceBaseTest, FailedNavigation) {
  CreateEchoImpl(main_rfh_);

  auto navigation_simulator =
      NavigationSimulator::CreateRendererInitiated(GURL(kFooOrigin), main_rfh_);
  navigation_simulator->Fail(net::ERR_TIMED_OUT);
  navigation_simulator->CommitErrorPage();

  EXPECT_FALSE(is_echo_impl_alive_);
}

TEST_F(FrameServiceBaseTest, DeleteContents) {
  CreateEchoImpl(main_rfh_);
  DeleteContents();
  EXPECT_FALSE(is_echo_impl_alive_);
}

}  // namespace content
