// Copyright (c) 2011 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/ftp/ftp_auth_cache.h"

#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/auth.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using base::ASCIIToUTF16;
using net::FtpAuthCache;

namespace {

const base::string16 kBogus(ASCIIToUTF16("bogus"));
const base::string16 kOthername(ASCIIToUTF16("othername"));
const base::string16 kOtherword(ASCIIToUTF16("otherword"));
const base::string16 kPassword(ASCIIToUTF16("password"));
const base::string16 kPassword1(ASCIIToUTF16("password1"));
const base::string16 kPassword2(ASCIIToUTF16("password2"));
const base::string16 kPassword3(ASCIIToUTF16("password3"));
const base::string16 kUsername(ASCIIToUTF16("username"));
const base::string16 kUsername1(ASCIIToUTF16("username1"));
const base::string16 kUsername2(ASCIIToUTF16("username2"));
const base::string16 kUsername3(ASCIIToUTF16("username3"));

}  // namespace

TEST(FtpAuthCacheTest, LookupAddRemove) {
  FtpAuthCache cache;

  GURL origin1("ftp://foo1");
  GURL origin2("ftp://foo2");

  // Lookup non-existent entry.
  EXPECT_TRUE(cache.Lookup(origin1) == NULL);

  // Add entry for origin1.
  cache.Add(origin1, net::AuthCredentials(kUsername1, kPassword1));
  FtpAuthCache::Entry* entry1 = cache.Lookup(origin1);
  ASSERT_TRUE(entry1);
  EXPECT_EQ(origin1, entry1->origin);
  EXPECT_EQ(kUsername1, entry1->credentials.username());
  EXPECT_EQ(kPassword1, entry1->credentials.password());

  // Add an entry for origin2.
  cache.Add(origin2, net::AuthCredentials(kUsername2, kPassword2));
  FtpAuthCache::Entry* entry2 = cache.Lookup(origin2);
  ASSERT_TRUE(entry2);
  EXPECT_EQ(origin2, entry2->origin);
  EXPECT_EQ(kUsername2, entry2->credentials.username());
  EXPECT_EQ(kPassword2, entry2->credentials.password());

  // The original entry1 should still be there.
  EXPECT_EQ(entry1, cache.Lookup(origin1));

  // Overwrite the entry for origin1.
  cache.Add(origin1, net::AuthCredentials(kUsername3, kPassword3));
  FtpAuthCache::Entry* entry3 = cache.Lookup(origin1);
  ASSERT_TRUE(entry3);
  EXPECT_EQ(origin1, entry3->origin);
  EXPECT_EQ(kUsername3, entry3->credentials.username());
  EXPECT_EQ(kPassword3, entry3->credentials.password());

  // Remove entry of origin1.
  cache.Remove(origin1, net::AuthCredentials(kUsername3, kPassword3));
  EXPECT_TRUE(cache.Lookup(origin1) == NULL);

  // Remove non-existent entry.
  cache.Remove(origin1, net::AuthCredentials(kUsername3, kPassword3));
  EXPECT_TRUE(cache.Lookup(origin1) == NULL);
}

// Check that if the origin differs only by port number, it is considered
// a separate origin.
TEST(FtpAuthCacheTest, LookupWithPort) {
  FtpAuthCache cache;

  GURL origin1("ftp://foo:80");
  GURL origin2("ftp://foo:21");

  cache.Add(origin1, net::AuthCredentials(kUsername, kPassword));
  cache.Add(origin2, net::AuthCredentials(kUsername, kPassword));

  EXPECT_NE(cache.Lookup(origin1), cache.Lookup(origin2));
}

TEST(FtpAuthCacheTest, NormalizedKey) {
  // GURL is automatically canonicalized. Hence the following variations in
  // url format should all map to the same entry (case insensitive host,
  // default port of 21).

  FtpAuthCache cache;

  // Add.
  cache.Add(GURL("ftp://HoSt:21"), net::AuthCredentials(kUsername, kPassword));

  // Lookup.
  FtpAuthCache::Entry* entry1 = cache.Lookup(GURL("ftp://HoSt:21"));
  ASSERT_TRUE(entry1);
  EXPECT_EQ(entry1, cache.Lookup(GURL("ftp://host:21")));
  EXPECT_EQ(entry1, cache.Lookup(GURL("ftp://host")));

  // Overwrite.
  cache.Add(GURL("ftp://host"), net::AuthCredentials(kOthername, kOtherword));
  FtpAuthCache::Entry* entry2 = cache.Lookup(GURL("ftp://HoSt:21"));
  ASSERT_TRUE(entry2);
  EXPECT_EQ(GURL("ftp://host"), entry2->origin);
  EXPECT_EQ(kOthername, entry2->credentials.username());
  EXPECT_EQ(kOtherword, entry2->credentials.password());

  // Remove
  cache.Remove(GURL("ftp://HOsT"),
               net::AuthCredentials(kOthername, kOtherword));
  EXPECT_TRUE(cache.Lookup(GURL("ftp://host")) == NULL);
}

TEST(FtpAuthCacheTest, OnlyRemoveMatching) {
  FtpAuthCache cache;

  cache.Add(GURL("ftp://host"), net::AuthCredentials(kUsername, kPassword));
  EXPECT_TRUE(cache.Lookup(GURL("ftp://host")));

  // Auth data doesn't match, shouldn't remove.
  cache.Remove(GURL("ftp://host"), net::AuthCredentials(kBogus, kBogus));
  EXPECT_TRUE(cache.Lookup(GURL("ftp://host")));

  // Auth data matches, should remove.
  cache.Remove(GURL("ftp://host"), net::AuthCredentials(kUsername, kPassword));
  EXPECT_TRUE(cache.Lookup(GURL("ftp://host")) == NULL);
}

TEST(FtpAuthCacheTest, EvictOldEntries) {
  FtpAuthCache cache;

  for (size_t i = 0; i < FtpAuthCache::kMaxEntries; i++) {
    cache.Add(GURL("ftp://host" + base::IntToString(i)),
              net::AuthCredentials(kUsername, kPassword));
  }

  // No entries should be evicted before reaching the limit.
  for (size_t i = 0; i < FtpAuthCache::kMaxEntries; i++) {
    EXPECT_TRUE(cache.Lookup(GURL("ftp://host" + base::IntToString(i))));
  }

  // Adding one entry should cause eviction of the first entry.
  cache.Add(GURL("ftp://last_host"),
            net::AuthCredentials(kUsername, kPassword));
  EXPECT_TRUE(cache.Lookup(GURL("ftp://host0")) == NULL);

  // Remaining entries should not get evicted.
  for (size_t i = 1; i < FtpAuthCache::kMaxEntries; i++) {
    EXPECT_TRUE(cache.Lookup(GURL("ftp://host" + base::IntToString(i))));
  }
  EXPECT_TRUE(cache.Lookup(GURL("ftp://last_host")));
}
