// 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 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")));
}
