// Copyright (c) 2010 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 "net/http/url_security_manager.h"

#include "base/basictypes.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
#include "net/http/http_auth_filter.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

struct TestData {
  const char* url;
  bool succeds_in_windows_default;
  bool succeeds_in_whitelist;
};

const char* kTestAuthWhitelist = "*example.com,*foobar.com,baz";

// Under Windows the following will be allowed by default:
//    localhost
//    host names without a period.
// In Posix systems (or on Windows if a whitelist is specified explicitly),
// everything depends on the whitelist.
const TestData kTestDataList[] = {
  { "http://localhost", true, false },
  { "http://bat", true, false },
  { "http://www.example.com", false, true },
  { "http://example.com", false, true },
  { "http://foobar.com", false, true },
  { "http://boo.foobar.com", false, true },
  { "http://baz", true, true },
  { "http://www.exampl.com", false, false },
  { "http://example.org", false, false },
  { "http://foobar.net", false, false },
  { "http://boo.fubar.com", false, false },
};

}  // namespace

TEST(URLSecurityManager, UseDefaultCredentials) {
  HttpAuthFilterWhitelist* auth_filter = new HttpAuthFilterWhitelist(
      kTestAuthWhitelist);
  ASSERT_TRUE(auth_filter);
  // The URL security manager takes ownership of |auth_filter|.
  scoped_ptr<URLSecurityManager> url_security_manager(
      URLSecurityManager::Create(auth_filter, NULL));
  ASSERT_TRUE(url_security_manager.get());

  for (size_t i = 0; i < arraysize(kTestDataList); ++i) {
    GURL gurl(kTestDataList[i].url);
    bool can_use_default =
        url_security_manager->CanUseDefaultCredentials(gurl);

    EXPECT_EQ(kTestDataList[i].succeeds_in_whitelist, can_use_default)
        << " Run: " << i << " URL: '" << gurl << "'";
  }
}

TEST(URLSecurityManager, CanDelegate) {
  HttpAuthFilterWhitelist* auth_filter = new HttpAuthFilterWhitelist(
      kTestAuthWhitelist);
  ASSERT_TRUE(auth_filter);
  // The URL security manager takes ownership of |auth_filter|.
  scoped_ptr<URLSecurityManager> url_security_manager(
      URLSecurityManager::Create(NULL, auth_filter));
  ASSERT_TRUE(url_security_manager.get());

  for (size_t i = 0; i < arraysize(kTestDataList); ++i) {
    GURL gurl(kTestDataList[i].url);
    bool can_delegate = url_security_manager->CanDelegate(gurl);
    EXPECT_EQ(kTestDataList[i].succeeds_in_whitelist, can_delegate)
        << " Run: " << i << " URL: '" << gurl << "'";
  }
}

TEST(URLSecurityManager, CanDelegate_NoWhitelist) {
  // Nothing can delegate in this case.
  scoped_ptr<URLSecurityManager> url_security_manager(
      URLSecurityManager::Create(NULL, NULL));
  ASSERT_TRUE(url_security_manager.get());

  for (size_t i = 0; i < arraysize(kTestDataList); ++i) {
    GURL gurl(kTestDataList[i].url);
    bool can_delegate = url_security_manager->CanDelegate(gurl);
    EXPECT_FALSE(can_delegate);
  }
}


}  // namespace net
