// Copyright 2015 Google Inc. 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 "googleurl/src/gurl.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.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
