// Copyright 2015 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
//
//     https://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 "cobalt/dom/location.h"

#include "base/memory/ref_counted.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using ::testing::Return;
using ::testing::StrictMock;
using ::testing::_;

namespace cobalt {
namespace dom {

// Base class to assist in mocking Location's use of its navigation and
// security callbacks.
class LocationCallbackInterface {
 public:
  virtual bool CanLoad(const GURL& /*url*/, bool /*did_redirect*/) = 0;
  virtual void FireHashChangeEvent() = 0;
  virtual void Navigate(const GURL& /* url*/) = 0;
};

class MockSecurityCallback : public LocationCallbackInterface {
 public:
  MOCK_METHOD2(CanLoad, bool(const GURL&, bool));
  MOCK_METHOD0(FireHashChangeEvent, void());
  MOCK_METHOD1(Navigate, void(const GURL&));
  csp::SecurityCallback LoadCb() {
    return base::Bind(&MockSecurityCallback::CanLoad, base::Unretained(this));
  }
  base::Closure HashChangeCb() {
    return base::Bind(&MockSecurityCallback::FireHashChangeEvent,
                      base::Unretained(this));
  }
  base::Callback<void(const GURL&)> NavigateCb() {
    return base::Bind(&MockSecurityCallback::Navigate, base::Unretained(this));
  }
};

// Tests modifying the location with both a "strict" and a "permissive" policy.
// If param is false, we return false from the security callback, and the
// navigate callback should *not* be called.
// If param is true, we return true from the security callback, and expect the
// navigate callback to be called with our expected new URL.
class LocationTestWithParams : public testing::TestWithParam<bool> {
 protected:
  void Init(const GURL& url, const base::Closure& hashchange_callback,
            const base::Callback<void(const GURL&)>& navigation_callback,
            const csp::SecurityCallback& security_callback) {
    location_ = new Location(url, hashchange_callback, navigation_callback,
                             security_callback);
  }

  scoped_refptr<Location> location_;
};

TEST_P(LocationTestWithParams, SetHash) {
  StrictMock<MockSecurityCallback> security_mock;
  GURL url("https://www.example.com/foo");
  GURL new_url("https://www.example.com/foo#bar");
  bool permissive = GetParam();
  Init(url, security_mock.HashChangeCb(), security_mock.NavigateCb(),
       security_mock.LoadCb());

  EXPECT_CALL(security_mock, CanLoad(new_url, _)).WillOnce(Return(permissive));
  if (permissive) {
    EXPECT_CALL(security_mock, FireHashChangeEvent());
  }
  location_->set_hash("bar");
}

TEST_P(LocationTestWithParams, SetHost) {
  StrictMock<MockSecurityCallback> security_mock;
  GURL url("https://www.example.com:1234");
  GURL new_url("https://www.google.com:5678");
  bool permissive = GetParam();
  Init(url, security_mock.HashChangeCb(), security_mock.NavigateCb(),
       security_mock.LoadCb());

  EXPECT_CALL(security_mock, CanLoad(new_url, _)).WillOnce(Return(permissive));
  if (permissive) {
    EXPECT_CALL(security_mock, Navigate(new_url));
  }
  location_->set_host("www.google.com:5678");
}

TEST_P(LocationTestWithParams, SetHostname) {
  StrictMock<MockSecurityCallback> security_mock;
  GURL url("https://www.example.com");
  GURL new_url("https://www.google.com");
  bool permissive = GetParam();
  Init(url, security_mock.HashChangeCb(), security_mock.NavigateCb(),
       security_mock.LoadCb());

  EXPECT_CALL(security_mock, CanLoad(new_url, _)).WillOnce(Return(permissive));
  if (permissive) {
    EXPECT_CALL(security_mock, Navigate(new_url));
  }
  location_->set_hostname("www.google.com");
}

TEST_P(LocationTestWithParams, SetHref) {
  StrictMock<MockSecurityCallback> security_mock;
  GURL url("https://www.example.com");
  GURL new_url("http://www.google.com:1234/path");
  bool permissive = GetParam();
  Init(url, security_mock.HashChangeCb(), security_mock.NavigateCb(),
       security_mock.LoadCb());

  EXPECT_CALL(security_mock, CanLoad(new_url, _)).WillOnce(Return(permissive));
  if (permissive) {
    EXPECT_CALL(security_mock, Navigate(new_url));
  }
  location_->set_href(new_url.spec());
}

TEST_P(LocationTestWithParams, SetProtocol) {
  StrictMock<MockSecurityCallback> security_mock;
  GURL url("https://www.example.com");
  GURL new_url("http://www.example.com");
  bool permissive = GetParam();
  Init(url, security_mock.HashChangeCb(), security_mock.NavigateCb(),
       security_mock.LoadCb());

  EXPECT_CALL(security_mock, CanLoad(new_url, _)).WillOnce(Return(permissive));
  if (permissive) {
    EXPECT_CALL(security_mock, Navigate(new_url));
  }
  location_->set_protocol("http");
}

INSTANTIATE_TEST_CASE_P(SecurityTests, LocationTestWithParams,
                        ::testing::Bool());

}  // namespace dom
}  // namespace cobalt
