// Copyright 2013 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 "chrome/browser/extensions/chrome_app_sorting.h"

#include <memory>

#include "chrome/browser/extensions/extension_prefs_unittest.h"
#include "components/crx_file/id_util.h"
#include "components/sync/model/string_ordinal.h"
#include "extensions/common/constants.h"
#include "extensions/common/manifest_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

namespace keys = manifest_keys;

class ChromeAppSortingAppLocation : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    extension_ = prefs_.AddExtension("not_an_app");
    // Non-apps should not have any app launch ordinal or page ordinal.
    prefs()->OnExtensionInstalled(extension_.get(),
                                  Extension::ENABLED,
                                  syncer::StringOrdinal(),
                                  std::string());
  }

  void Verify() override {
    EXPECT_FALSE(
        app_sorting()->GetAppLaunchOrdinal(extension_->id()).IsValid());
    EXPECT_FALSE(app_sorting()->GetPageOrdinal(extension_->id()).IsValid());
  }

 private:
  scoped_refptr<Extension> extension_;
};
TEST_F(ChromeAppSortingAppLocation, ChromeAppSortingAppLocation) {}

class ChromeAppSortingAppLaunchOrdinal : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    // No extensions yet.
    syncer::StringOrdinal page = syncer::StringOrdinal::CreateInitialOrdinal();
    EXPECT_TRUE(syncer::StringOrdinal::CreateInitialOrdinal().Equals(
        app_sorting()->CreateNextAppLaunchOrdinal(page)));

    extension_ = prefs_.AddApp("on_extension_installed");
    EXPECT_FALSE(prefs()->IsExtensionDisabled(extension_->id()));
    prefs()->OnExtensionInstalled(extension_.get(),
                                  Extension::ENABLED,
                                  syncer::StringOrdinal(),
                                  std::string());
  }

  void Verify() override {
    syncer::StringOrdinal launch_ordinal =
        app_sorting()->GetAppLaunchOrdinal(extension_->id());
    syncer::StringOrdinal page_ordinal =
        syncer::StringOrdinal::CreateInitialOrdinal();

    // Extension should have been assigned a valid StringOrdinal.
    EXPECT_TRUE(launch_ordinal.IsValid());
    EXPECT_TRUE(launch_ordinal.LessThan(
        app_sorting()->CreateNextAppLaunchOrdinal(page_ordinal)));
    // Set a new launch ordinal of and verify it comes after.
    app_sorting()->SetAppLaunchOrdinal(
        extension_->id(),
        app_sorting()->CreateNextAppLaunchOrdinal(page_ordinal));
    syncer::StringOrdinal new_launch_ordinal =
        app_sorting()->GetAppLaunchOrdinal(extension_->id());
    EXPECT_TRUE(launch_ordinal.LessThan(new_launch_ordinal));

    // This extension doesn't exist, so it should return an invalid
    // StringOrdinal.
    syncer::StringOrdinal invalid_app_launch_ordinal =
        app_sorting()->GetAppLaunchOrdinal("foo");
    EXPECT_FALSE(invalid_app_launch_ordinal.IsValid());
    EXPECT_EQ(-1, app_sorting()->PageStringOrdinalAsInteger(
        invalid_app_launch_ordinal));

    // The second page doesn't have any apps so its next launch ordinal should
    // be the first launch ordinal.
    syncer::StringOrdinal next_page = page_ordinal.CreateAfter();
    syncer::StringOrdinal next_page_app_launch_ordinal =
        app_sorting()->CreateNextAppLaunchOrdinal(next_page);
    EXPECT_TRUE(next_page_app_launch_ordinal.Equals(
        app_sorting()->CreateFirstAppLaunchOrdinal(next_page)));
  }

 private:
  scoped_refptr<Extension> extension_;
};
TEST_F(ChromeAppSortingAppLaunchOrdinal, ChromeAppSortingAppLaunchOrdinal) {}

class ChromeAppSortingPageOrdinal : public ExtensionPrefsTest {
 public:
  void Initialize() override {
    extension_ = prefs_.AddApp("page_ordinal");
    // Install with a page preference.
    first_page_ = syncer::StringOrdinal::CreateInitialOrdinal();
    prefs()->OnExtensionInstalled(extension_.get(),
                                  Extension::ENABLED,
                                  first_page_,
                                  std::string());
    EXPECT_TRUE(first_page_.Equals(
        app_sorting()->GetPageOrdinal(extension_->id())));
    EXPECT_EQ(0, app_sorting()->PageStringOrdinalAsInteger(first_page_));

    scoped_refptr<Extension> extension2 = prefs_.AddApp("page_ordinal_2");
    // Install without any page preference.
    prefs()->OnExtensionInstalled(extension2.get(),
                                  Extension::ENABLED,
                                  syncer::StringOrdinal(),
                                  std::string());
    EXPECT_TRUE(first_page_.Equals(
        app_sorting()->GetPageOrdinal(extension2->id())));
  }
  void Verify() override {
    // Set the page ordinal.
    syncer::StringOrdinal new_page = first_page_.CreateAfter();
    app_sorting()->SetPageOrdinal(extension_->id(), new_page);
    // Verify the page ordinal.
    EXPECT_TRUE(
        new_page.Equals(app_sorting()->GetPageOrdinal(extension_->id())));
    EXPECT_EQ(1, app_sorting()->PageStringOrdinalAsInteger(new_page));

    // This extension doesn't exist, so it should return an invalid
    // StringOrdinal.
    EXPECT_FALSE(app_sorting()->GetPageOrdinal("foo").IsValid());
  }

 private:
  syncer::StringOrdinal first_page_;
  scoped_refptr<Extension> extension_;
};
TEST_F(ChromeAppSortingPageOrdinal, ChromeAppSortingPageOrdinal) {}

// Ensure that ChromeAppSorting is able to properly initialize off a set
// of old page and app launch indices and properly convert them.
class ChromeAppSortingInitialize : public PrefsPrepopulatedTestBase {
 public:
  ChromeAppSortingInitialize() {}
  ~ChromeAppSortingInitialize() override {}

  void Initialize() override {
    // A preference determining the order of which the apps appear on the NTP.
    const char kPrefAppLaunchIndexDeprecated[] = "app_launcher_index";
    // A preference determining the page on which an app appears in the NTP.
    const char kPrefPageIndexDeprecated[] = "page_index";

    // Setup the deprecated preferences.
    prefs()->UpdateExtensionPref(extension1()->id(),
                                 kPrefAppLaunchIndexDeprecated,
                                 std::make_unique<base::Value>(0));
    prefs()->UpdateExtensionPref(extension1()->id(), kPrefPageIndexDeprecated,
                                 std::make_unique<base::Value>(0));

    prefs()->UpdateExtensionPref(extension2()->id(),
                                 kPrefAppLaunchIndexDeprecated,
                                 std::make_unique<base::Value>(1));
    prefs()->UpdateExtensionPref(extension2()->id(), kPrefPageIndexDeprecated,
                                 std::make_unique<base::Value>(0));

    prefs()->UpdateExtensionPref(extension3()->id(),
                                 kPrefAppLaunchIndexDeprecated,
                                 std::make_unique<base::Value>(0));
    prefs()->UpdateExtensionPref(extension3()->id(), kPrefPageIndexDeprecated,
                                 std::make_unique<base::Value>(1));

    // We insert the ids in reverse order so that we have to deal with the
    // element on the 2nd page before the 1st page is seen.
    ExtensionIdList ids;
    ids.push_back(extension3()->id());
    ids.push_back(extension2()->id());
    ids.push_back(extension1()->id());

    app_sorting()->MigrateAppIndex(ids);
  }
  void Verify() override {
    syncer::StringOrdinal first_ordinal =
        syncer::StringOrdinal::CreateInitialOrdinal();

    EXPECT_TRUE(first_ordinal.Equals(
        app_sorting()->GetAppLaunchOrdinal(extension1()->id())));
    EXPECT_TRUE(first_ordinal.LessThan(
        app_sorting()->GetAppLaunchOrdinal(extension2()->id())));
    EXPECT_TRUE(first_ordinal.Equals(
        app_sorting()->GetAppLaunchOrdinal(extension3()->id())));

    EXPECT_TRUE(first_ordinal.Equals(
        app_sorting()->GetPageOrdinal(extension1()->id())));
    EXPECT_TRUE(first_ordinal.Equals(
        app_sorting()->GetPageOrdinal(extension2()->id())));
    EXPECT_TRUE(first_ordinal.LessThan(
        app_sorting()->GetPageOrdinal(extension3()->id())));
  }
};
TEST_F(ChromeAppSortingInitialize, ChromeAppSortingInitialize) {}

// Make sure that initialization still works when no extensions are present
// (i.e. make sure that the web store icon is still loaded into the map).
class ChromeAppSortingInitializeWithNoApps : public PrefsPrepopulatedTestBase {
 public:
  ChromeAppSortingInitializeWithNoApps() {}
  ~ChromeAppSortingInitializeWithNoApps() override {}

  void Initialize() override {
    // Make sure that the web store has valid ordinals.
    syncer::StringOrdinal initial_ordinal =
        syncer::StringOrdinal::CreateInitialOrdinal();
    app_sorting()->SetPageOrdinal(extensions::kWebStoreAppId,
                                  initial_ordinal);
    app_sorting()->SetAppLaunchOrdinal(extensions::kWebStoreAppId,
                                       initial_ordinal);
  }
  void Verify() override {
    syncer::StringOrdinal page =
        app_sorting()->GetPageOrdinal(extensions::kWebStoreAppId);
    EXPECT_TRUE(page.IsValid());

    ChromeAppSorting::PageOrdinalMap::iterator page_it =
        app_sorting()->ntp_ordinal_map_.find(page);
    EXPECT_TRUE(page_it != app_sorting()->ntp_ordinal_map_.end());

    syncer::StringOrdinal app_launch =
        app_sorting()->GetPageOrdinal(extensions::kWebStoreAppId);
    EXPECT_TRUE(app_launch.IsValid());

    ChromeAppSorting::AppLaunchOrdinalMap::iterator app_launch_it =
        page_it->second.find(app_launch);
    EXPECT_TRUE(app_launch_it != page_it->second.end());
  }
};
TEST_F(ChromeAppSortingInitializeWithNoApps,
       ChromeAppSortingInitializeWithNoApps) {}

// Tests the application index to ordinal migration code for values that
// shouldn't be converted. This should be removed when the migrate code
// is taken out.
// http://crbug.com/107376
class ChromeAppSortingMigrateAppIndexInvalid
    : public PrefsPrepopulatedTestBase {
 public:
  ChromeAppSortingMigrateAppIndexInvalid() {}
  ~ChromeAppSortingMigrateAppIndexInvalid() override {}

  void Initialize() override {
    // A preference determining the order of which the apps appear on the NTP.
    const char kPrefAppLaunchIndexDeprecated[] = "app_launcher_index";
    // A preference determining the page on which an app appears in the NTP.
    const char kPrefPageIndexDeprecated[] = "page_index";

    // Setup the deprecated preference.
    prefs()->UpdateExtensionPref(extension1()->id(),
                                 kPrefAppLaunchIndexDeprecated,
                                 std::make_unique<base::Value>(0));
    prefs()->UpdateExtensionPref(extension1()->id(), kPrefPageIndexDeprecated,
                                 std::make_unique<base::Value>(-1));
  }
  void Verify() override {
    // Make sure that the invalid page_index wasn't converted over.
    EXPECT_FALSE(app_sorting()->GetAppLaunchOrdinal(
        extension1()->id()).IsValid());
  }
};
TEST_F(ChromeAppSortingMigrateAppIndexInvalid,
       ChromeAppSortingMigrateAppIndexInvalid) {}

class ChromeAppSortingFixNTPCollisionsAllCollide
    : public PrefsPrepopulatedTestBase {
 public:
  ChromeAppSortingFixNTPCollisionsAllCollide() {}
  ~ChromeAppSortingFixNTPCollisionsAllCollide() override {}

  void Initialize() override {
    repeated_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();

    app_sorting()->SetAppLaunchOrdinal(extension1()->id(),
                                       repeated_ordinal_);
    app_sorting()->SetPageOrdinal(extension1()->id(), repeated_ordinal_);

    app_sorting()->SetAppLaunchOrdinal(extension2()->id(), repeated_ordinal_);
    app_sorting()->SetPageOrdinal(extension2()->id(), repeated_ordinal_);

    app_sorting()->SetAppLaunchOrdinal(extension3()->id(), repeated_ordinal_);
    app_sorting()->SetPageOrdinal(extension3()->id(), repeated_ordinal_);

    app_sorting()->FixNTPOrdinalCollisions();
  }
  void Verify() override {
    syncer::StringOrdinal extension1_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension1()->id());
    syncer::StringOrdinal extension2_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension2()->id());
    syncer::StringOrdinal extension3_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension3()->id());

    // The overlapping extensions should have be adjusted so that they are
    // sorted by their id.
    EXPECT_EQ(extension1()->id() < extension2()->id(),
              extension1_app_launch.LessThan(extension2_app_launch));
    EXPECT_EQ(extension1()->id() < extension3()->id(),
              extension1_app_launch.LessThan(extension3_app_launch));
    EXPECT_EQ(extension2()->id() < extension3()->id(),
              extension2_app_launch.LessThan(extension3_app_launch));

    // The page ordinal should be unchanged.
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension1()->id()).Equals(
        repeated_ordinal_));
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension2()->id()).Equals(
        repeated_ordinal_));
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension3()->id()).Equals(
        repeated_ordinal_));
  }

 private:
  syncer::StringOrdinal repeated_ordinal_;
};
TEST_F(ChromeAppSortingFixNTPCollisionsAllCollide,
       ChromeAppSortingFixNTPCollisionsAllCollide) {}

class ChromeAppSortingFixNTPCollisionsSomeCollideAtStart
    : public PrefsPrepopulatedTestBase {
 public:
  ChromeAppSortingFixNTPCollisionsSomeCollideAtStart() {}
  ~ChromeAppSortingFixNTPCollisionsSomeCollideAtStart() override {}

  void Initialize() override {
    first_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
    syncer::StringOrdinal second_ordinal = first_ordinal_.CreateAfter();

    // Have the first two extension in the same position, with a third
    // (non-colliding) extension after.

    app_sorting()->SetAppLaunchOrdinal(extension1()->id(), first_ordinal_);
    app_sorting()->SetPageOrdinal(extension1()->id(), first_ordinal_);

    app_sorting()->SetAppLaunchOrdinal(extension2()->id(), first_ordinal_);
    app_sorting()->SetPageOrdinal(extension2()->id(), first_ordinal_);

    app_sorting()->SetAppLaunchOrdinal(extension3()->id(), second_ordinal);
    app_sorting()->SetPageOrdinal(extension3()->id(), first_ordinal_);

    app_sorting()->FixNTPOrdinalCollisions();
  }
  void Verify() override {
    syncer::StringOrdinal extension1_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension1()->id());
    syncer::StringOrdinal extension2_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension2()->id());
    syncer::StringOrdinal extension3_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension3()->id());

    // The overlapping extensions should have be adjusted so that they are
    // sorted by their id, but they both should be before ext3, which wasn't
    // overlapping.
    EXPECT_EQ(extension1()->id() < extension2()->id(),
              extension1_app_launch.LessThan(extension2_app_launch));
    EXPECT_TRUE(extension1_app_launch.LessThan(extension3_app_launch));
    EXPECT_TRUE(extension2_app_launch.LessThan(extension3_app_launch));

    // The page ordinal should be unchanged.
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension1()->id()).Equals(
        first_ordinal_));
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension2()->id()).Equals(
        first_ordinal_));
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension3()->id()).Equals(
        first_ordinal_));
  }

 private:
  syncer::StringOrdinal first_ordinal_;
};
TEST_F(ChromeAppSortingFixNTPCollisionsSomeCollideAtStart,
       ChromeAppSortingFixNTPCollisionsSomeCollideAtStart) {}

class ChromeAppSortingFixNTPCollisionsSomeCollideAtEnd
    : public PrefsPrepopulatedTestBase {
 public:
  ChromeAppSortingFixNTPCollisionsSomeCollideAtEnd() {}
  ~ChromeAppSortingFixNTPCollisionsSomeCollideAtEnd() override {}

  void Initialize() override {
    first_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
    syncer::StringOrdinal second_ordinal = first_ordinal_.CreateAfter();

    // Have the first extension in a non-colliding position, followed by two
    // two extension in the same position.

    app_sorting()->SetAppLaunchOrdinal(extension1()->id(), first_ordinal_);
    app_sorting()->SetPageOrdinal(extension1()->id(), first_ordinal_);

    app_sorting()->SetAppLaunchOrdinal(extension2()->id(), second_ordinal);
    app_sorting()->SetPageOrdinal(extension2()->id(), first_ordinal_);

    app_sorting()->SetAppLaunchOrdinal(extension3()->id(), second_ordinal);
    app_sorting()->SetPageOrdinal(extension3()->id(), first_ordinal_);

    app_sorting()->FixNTPOrdinalCollisions();
  }
  void Verify() override {
    syncer::StringOrdinal extension1_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension1()->id());
    syncer::StringOrdinal extension2_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension2()->id());
    syncer::StringOrdinal extension3_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension3()->id());

    // The overlapping extensions should have be adjusted so that they are
    // sorted by their id, but they both should be after ext1, which wasn't
    // overlapping.
    EXPECT_TRUE(extension1_app_launch.LessThan(extension2_app_launch));
    EXPECT_TRUE(extension1_app_launch.LessThan(extension3_app_launch));
    EXPECT_EQ(extension2()->id() < extension3()->id(),
              extension2_app_launch.LessThan(extension3_app_launch));

    // The page ordinal should be unchanged.
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension1()->id()).Equals(
        first_ordinal_));
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension2()->id()).Equals(
        first_ordinal_));
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension3()->id()).Equals(
        first_ordinal_));
  }

 private:
  syncer::StringOrdinal first_ordinal_;
};
TEST_F(ChromeAppSortingFixNTPCollisionsSomeCollideAtEnd,
       ChromeAppSortingFixNTPCollisionsSomeCollideAtEnd) {}

class ChromeAppSortingFixNTPCollisionsTwoCollisions
    : public PrefsPrepopulatedTestBase {
 public:
  ChromeAppSortingFixNTPCollisionsTwoCollisions() {}
  ~ChromeAppSortingFixNTPCollisionsTwoCollisions() override {}

  void Initialize() override {
    first_ordinal_ = syncer::StringOrdinal::CreateInitialOrdinal();
    syncer::StringOrdinal second_ordinal = first_ordinal_.CreateAfter();

    // Have two extensions colliding, followed by two more colliding extensions.
    app_sorting()->SetAppLaunchOrdinal(extension1()->id(), first_ordinal_);
    app_sorting()->SetPageOrdinal(extension1()->id(), first_ordinal_);

    app_sorting()->SetAppLaunchOrdinal(extension2()->id(), first_ordinal_);
    app_sorting()->SetPageOrdinal(extension2()->id(), first_ordinal_);

    app_sorting()->SetAppLaunchOrdinal(extension3()->id(), second_ordinal);
    app_sorting()->SetPageOrdinal(extension3()->id(), first_ordinal_);

    app_sorting()->SetAppLaunchOrdinal(extension4()->id(), second_ordinal);
    app_sorting()->SetPageOrdinal(extension4()->id(), first_ordinal_);

    app_sorting()->FixNTPOrdinalCollisions();
  }
  void Verify() override {
    syncer::StringOrdinal extension1_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension1()->id());
    syncer::StringOrdinal extension2_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension2()->id());
    syncer::StringOrdinal extension3_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension3()->id());
    syncer::StringOrdinal extension4_app_launch =
        app_sorting()->GetAppLaunchOrdinal(extension4()->id());

    // The overlapping extensions should have be adjusted so that they are
    // sorted by their id, with |ext1| and |ext2| appearing before |ext3| and
    // |ext4|.
    EXPECT_TRUE(extension1_app_launch.LessThan(extension3_app_launch));
    EXPECT_TRUE(extension1_app_launch.LessThan(extension4_app_launch));
    EXPECT_TRUE(extension2_app_launch.LessThan(extension3_app_launch));
    EXPECT_TRUE(extension2_app_launch.LessThan(extension4_app_launch));

    EXPECT_EQ(extension1()->id() < extension2()->id(),
              extension1_app_launch.LessThan(extension2_app_launch));
    EXPECT_EQ(extension3()->id() < extension4()->id(),
              extension3_app_launch.LessThan(extension4_app_launch));

    // The page ordinal should be unchanged.
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension1()->id()).Equals(
        first_ordinal_));
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension2()->id()).Equals(
        first_ordinal_));
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension3()->id()).Equals(
        first_ordinal_));
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension4()->id()).Equals(
        first_ordinal_));
  }

 private:
  syncer::StringOrdinal first_ordinal_;
};
TEST_F(ChromeAppSortingFixNTPCollisionsTwoCollisions,
       ChromeAppSortingFixNTPCollisionsTwoCollisions) {}

class ChromeAppSortingEnsureValidOrdinals
    : public PrefsPrepopulatedTestBase {
 public :
  ChromeAppSortingEnsureValidOrdinals() {}
  ~ChromeAppSortingEnsureValidOrdinals() override {}

  void Initialize() override {}
  void Verify() override {
    // Give ext1 invalid ordinals and then check that EnsureValidOrdinals fixes
    // them.
    app_sorting()->SetAppLaunchOrdinal(extension1()->id(),
                                     syncer::StringOrdinal());
    app_sorting()->SetPageOrdinal(extension1()->id(), syncer::StringOrdinal());

    app_sorting()->EnsureValidOrdinals(extension1()->id(),
                                     syncer::StringOrdinal());

    EXPECT_TRUE(
        app_sorting()->GetAppLaunchOrdinal(extension1()->id()).IsValid());
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(extension1()->id()).IsValid());
  }
};
TEST_F(ChromeAppSortingEnsureValidOrdinals,
       ChromeAppSortingEnsureValidOrdinals) {}

class ChromeAppSortingPageOrdinalMapping : public PrefsPrepopulatedTestBase {
 public:
  ChromeAppSortingPageOrdinalMapping() {}
  ~ChromeAppSortingPageOrdinalMapping() override {}

  void Initialize() override {}
  void Verify() override {
    std::string ext_1 = "ext_1";
    std::string ext_2 = "ext_2";

    syncer::StringOrdinal first_ordinal =
        syncer::StringOrdinal::CreateInitialOrdinal();

    // Ensure attempting to removing a mapping with an invalid page doesn't
    // modify the map.
    EXPECT_TRUE(app_sorting()->ntp_ordinal_map_.empty());
    app_sorting()->RemoveOrdinalMapping(
        ext_1, first_ordinal, first_ordinal);
    EXPECT_TRUE(app_sorting()->ntp_ordinal_map_.empty());

    // Add new mappings.
    app_sorting()->AddOrdinalMapping(ext_1, first_ordinal, first_ordinal);
    app_sorting()->AddOrdinalMapping(ext_2, first_ordinal, first_ordinal);

    EXPECT_EQ(1U, app_sorting()->ntp_ordinal_map_.size());
    EXPECT_EQ(2U, app_sorting()->ntp_ordinal_map_[first_ordinal].size());

    ChromeAppSorting::AppLaunchOrdinalMap::iterator it =
        app_sorting()->ntp_ordinal_map_[first_ordinal].find(first_ordinal);
    EXPECT_EQ(ext_1, it->second);
    ++it;
    EXPECT_EQ(ext_2, it->second);

    app_sorting()->RemoveOrdinalMapping(ext_1, first_ordinal, first_ordinal);
    EXPECT_EQ(1U, app_sorting()->ntp_ordinal_map_.size());
    EXPECT_EQ(1U, app_sorting()->ntp_ordinal_map_[first_ordinal].size());

    it = app_sorting()->ntp_ordinal_map_[first_ordinal].find(first_ordinal);
    EXPECT_EQ(ext_2, it->second);

    // Ensure that attempting to remove an extension with a valid page and app
    // launch ordinals, but a unused id has no effect.
    app_sorting()->RemoveOrdinalMapping(
        "invalid_ext", first_ordinal, first_ordinal);
    EXPECT_EQ(1U, app_sorting()->ntp_ordinal_map_.size());
    EXPECT_EQ(1U, app_sorting()->ntp_ordinal_map_[first_ordinal].size());

    it = app_sorting()->ntp_ordinal_map_[first_ordinal].find(first_ordinal);
    EXPECT_EQ(ext_2, it->second);
  }
};
TEST_F(ChromeAppSortingPageOrdinalMapping,
       ChromeAppSortingPageOrdinalMapping) {}

class ChromeAppSortingPreinstalledAppsBase : public PrefsPrepopulatedTestBase {
 public:
  ChromeAppSortingPreinstalledAppsBase() {
    base::DictionaryValue simple_dict;
    simple_dict.SetString(keys::kVersion, "1.0.0.0");
    simple_dict.SetString(keys::kName, "unused");
    simple_dict.SetString(keys::kApp, "true");
    simple_dict.SetString(keys::kLaunchLocalPath, "fake.html");

    std::string error;
    app1_scoped_ = Extension::Create(
        prefs_.temp_dir().AppendASCII("app1_"), Manifest::EXTERNAL_PREF,
        simple_dict, Extension::NO_FLAGS, &error);
    prefs()->OnExtensionInstalled(app1_scoped_.get(),
                                  Extension::ENABLED,
                                  syncer::StringOrdinal(),
                                  std::string());

    app2_scoped_ = Extension::Create(
        prefs_.temp_dir().AppendASCII("app2_"), Manifest::EXTERNAL_PREF,
        simple_dict, Extension::NO_FLAGS, &error);
    prefs()->OnExtensionInstalled(app2_scoped_.get(),
                                  Extension::ENABLED,
                                  syncer::StringOrdinal(),
                                  std::string());

    app1_ = app1_scoped_.get();
    app2_ = app2_scoped_.get();
  }
  ~ChromeAppSortingPreinstalledAppsBase() override {}

 protected:
  // Weak references, for convenience.
  Extension* app1_;
  Extension* app2_;

 private:
  scoped_refptr<Extension> app1_scoped_;
  scoped_refptr<Extension> app2_scoped_;
};

class ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage
    : public ChromeAppSortingPreinstalledAppsBase {
 public:
  ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage() {}
  ~ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage() override {}

  void Initialize() override {}
  void Verify() override {
    syncer::StringOrdinal page = syncer::StringOrdinal::CreateInitialOrdinal();

    syncer::StringOrdinal min =
        app_sorting()->GetMinOrMaxAppLaunchOrdinalsOnPage(
            page,
            ChromeAppSorting::MIN_ORDINAL);
    syncer::StringOrdinal max =
        app_sorting()->GetMinOrMaxAppLaunchOrdinalsOnPage(
            page,
            ChromeAppSorting::MAX_ORDINAL);
    EXPECT_TRUE(min.IsValid());
    EXPECT_TRUE(max.IsValid());
    EXPECT_TRUE(min.LessThan(max));

    // Ensure that the min and max values aren't set for empty pages.
    min = syncer::StringOrdinal();
    max = syncer::StringOrdinal();
    syncer::StringOrdinal empty_page = page.CreateAfter();
    EXPECT_FALSE(min.IsValid());
    EXPECT_FALSE(max.IsValid());
    min = app_sorting()->GetMinOrMaxAppLaunchOrdinalsOnPage(
        empty_page,
        ChromeAppSorting::MIN_ORDINAL);
    max = app_sorting()->GetMinOrMaxAppLaunchOrdinalsOnPage(
        empty_page,
        ChromeAppSorting::MAX_ORDINAL);
    EXPECT_FALSE(min.IsValid());
    EXPECT_FALSE(max.IsValid());
  }
};
TEST_F(ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage,
       ChromeAppSortingGetMinOrMaxAppLaunchOrdinalsOnPage) {}

// Make sure that empty pages aren't removed from the integer to ordinal
// mapping. See http://crbug.com/109802 for details.
class ChromeAppSortingKeepEmptyStringOrdinalPages
    : public ChromeAppSortingPreinstalledAppsBase {
 public:
  ChromeAppSortingKeepEmptyStringOrdinalPages() {}
  ~ChromeAppSortingKeepEmptyStringOrdinalPages() override {}

  void Initialize() override {
    syncer::StringOrdinal first_page =
        syncer::StringOrdinal::CreateInitialOrdinal();
    app_sorting()->SetPageOrdinal(app1_->id(), first_page);
    EXPECT_EQ(0, app_sorting()->PageStringOrdinalAsInteger(first_page));

    last_page_ = first_page.CreateAfter();
    app_sorting()->SetPageOrdinal(app2_->id(), last_page_);
    EXPECT_EQ(1, app_sorting()->PageStringOrdinalAsInteger(last_page_));

    // Move the second app to create an empty page.
    app_sorting()->SetPageOrdinal(app2_->id(), first_page);
    EXPECT_EQ(0, app_sorting()->PageStringOrdinalAsInteger(first_page));
  }
  void Verify() override {
    // Move the second app to a new empty page at the end, skipping over
    // the current empty page.
    last_page_ = last_page_.CreateAfter();
    app_sorting()->SetPageOrdinal(app2_->id(), last_page_);
    EXPECT_EQ(2, app_sorting()->PageStringOrdinalAsInteger(last_page_));
    EXPECT_TRUE(
        last_page_.Equals(app_sorting()->PageIntegerAsStringOrdinal(2)));
  }

 private:
  syncer::StringOrdinal last_page_;
};
TEST_F(ChromeAppSortingKeepEmptyStringOrdinalPages,
       ChromeAppSortingKeepEmptyStringOrdinalPages) {}

class ChromeAppSortingMakesFillerOrdinals
    : public ChromeAppSortingPreinstalledAppsBase {
 public:
  ChromeAppSortingMakesFillerOrdinals() {}
  ~ChromeAppSortingMakesFillerOrdinals() override {}

  void Initialize() override {
    syncer::StringOrdinal first_page =
        syncer::StringOrdinal::CreateInitialOrdinal();
    app_sorting()->SetPageOrdinal(app1_->id(), first_page);
    EXPECT_EQ(0, app_sorting()->PageStringOrdinalAsInteger(first_page));
  }
  void Verify() override {
    // Because the UI can add an unlimited number of empty pages without an app
    // on them, this test simulates dropping of an app on the 1st and 4th empty
    // pages (3rd and 6th pages by index) to ensure we don't crash and that
    // filler ordinals are created as needed. See: http://crbug.com/122214
    syncer::StringOrdinal page_three =
        app_sorting()->PageIntegerAsStringOrdinal(2);
    app_sorting()->SetPageOrdinal(app1_->id(), page_three);
    EXPECT_EQ(2, app_sorting()->PageStringOrdinalAsInteger(page_three));

    syncer::StringOrdinal page_six =
        app_sorting()->PageIntegerAsStringOrdinal(5);
    app_sorting()->SetPageOrdinal(app1_->id(), page_six);
    EXPECT_EQ(5, app_sorting()->PageStringOrdinalAsInteger(page_six));
  }
};
TEST_F(ChromeAppSortingMakesFillerOrdinals,
       ChromeAppSortingMakesFillerOrdinals) {}

class ChromeAppSortingDefaultOrdinalsBase : public ExtensionPrefsTest {
 public:
  ChromeAppSortingDefaultOrdinalsBase() {}
  ~ChromeAppSortingDefaultOrdinalsBase() override {}

  void Initialize() override {
    app_ = CreateApp("app");

    InitDefaultOrdinals();
    ChromeAppSorting::AppOrdinalsMap& sorting_defaults =
        app_sorting()->default_ordinals_;
    sorting_defaults[app_->id()].page_ordinal = default_page_ordinal_;
    sorting_defaults[app_->id()].app_launch_ordinal =
        default_app_launch_ordinal_;

    SetupUserOrdinals();
    InstallApps();
  }

 protected:
  scoped_refptr<Extension> CreateApp(const std::string& name) {
    base::DictionaryValue simple_dict;
    simple_dict.SetString(keys::kVersion, "1.0.0.0");
    simple_dict.SetString(keys::kName, name);
    simple_dict.SetString(keys::kApp, "true");
    simple_dict.SetString(keys::kLaunchLocalPath, "fake.html");

    std::string errors;
    scoped_refptr<Extension> app = Extension::Create(
        prefs_.temp_dir().AppendASCII(name), Manifest::EXTERNAL_PREF,
        simple_dict, Extension::NO_FLAGS, &errors);
    EXPECT_TRUE(app.get()) << errors;
    EXPECT_TRUE(crx_file::id_util::IdIsValid(app->id()));
    return app;
  }

  void InitDefaultOrdinals() {
    default_page_ordinal_ =
        syncer::StringOrdinal::CreateInitialOrdinal().CreateAfter();
    default_app_launch_ordinal_ =
        syncer::StringOrdinal::CreateInitialOrdinal().CreateBefore();
  }

  virtual void SetupUserOrdinals() {}

  virtual void InstallApps() {
    prefs()->OnExtensionInstalled(app_.get(),
                                  Extension::ENABLED,
                                  syncer::StringOrdinal(),
                                  std::string());
  }

  scoped_refptr<Extension> app_;
  syncer::StringOrdinal default_page_ordinal_;
  syncer::StringOrdinal default_app_launch_ordinal_;
};

// Tests that the app gets its default ordinals.
class ChromeAppSortingDefaultOrdinals
    : public ChromeAppSortingDefaultOrdinalsBase {
 public:
  ChromeAppSortingDefaultOrdinals() {}
  ~ChromeAppSortingDefaultOrdinals() override {}

  void Verify() override {
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(app_->id()).Equals(
        default_page_ordinal_));
    EXPECT_TRUE(app_sorting()->GetAppLaunchOrdinal(app_->id()).Equals(
        default_app_launch_ordinal_));
  }
};
TEST_F(ChromeAppSortingDefaultOrdinals,
       ChromeAppSortingDefaultOrdinals) {}

// Tests that the default page ordinal is overridden by install page ordinal.
class ChromeAppSortingDefaultOrdinalOverriddenByInstallPage
    : public ChromeAppSortingDefaultOrdinalsBase {
 public:
  ChromeAppSortingDefaultOrdinalOverriddenByInstallPage() {}
  ~ChromeAppSortingDefaultOrdinalOverriddenByInstallPage() override {}

  void Verify() override {
    EXPECT_FALSE(app_sorting()->GetPageOrdinal(app_->id()).Equals(
        default_page_ordinal_));
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(app_->id()).Equals(
        install_page_));
  }

 protected:
  void InstallApps() override {
    install_page_ = default_page_ordinal_.CreateAfter();
    prefs()->OnExtensionInstalled(app_.get(),
                                  Extension::ENABLED,
                                  install_page_,
                                  std::string());
  }

 private:
  syncer::StringOrdinal install_page_;
};
TEST_F(ChromeAppSortingDefaultOrdinalOverriddenByInstallPage,
       ChromeAppSortingDefaultOrdinalOverriddenByInstallPage) {}

// Tests that the default ordinals are overridden by user values.
class ChromeAppSortingDefaultOrdinalOverriddenByUserValue
    : public ChromeAppSortingDefaultOrdinalsBase {
 public:
  ChromeAppSortingDefaultOrdinalOverriddenByUserValue() {}
  ~ChromeAppSortingDefaultOrdinalOverriddenByUserValue() override {}

  void Verify() override {
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(app_->id()).Equals(
        user_page_ordinal_));
    EXPECT_TRUE(app_sorting()->GetAppLaunchOrdinal(app_->id()).Equals(
        user_app_launch_ordinal_));
  }

 protected:
  void SetupUserOrdinals() override {
    user_page_ordinal_ = default_page_ordinal_.CreateAfter();
    user_app_launch_ordinal_ = default_app_launch_ordinal_.CreateBefore();

    app_sorting()->SetPageOrdinal(app_->id(), user_page_ordinal_);
    app_sorting()->SetAppLaunchOrdinal(app_->id(), user_app_launch_ordinal_);
  }

 private:
  syncer::StringOrdinal user_page_ordinal_;
  syncer::StringOrdinal user_app_launch_ordinal_;
};
TEST_F(ChromeAppSortingDefaultOrdinalOverriddenByUserValue,
       ChromeAppSortingDefaultOrdinalOverriddenByUserValue) {}

// Tests that the default app launch ordinal is changed to avoid collision.
class ChromeAppSortingDefaultOrdinalNoCollision
    : public ChromeAppSortingDefaultOrdinalsBase {
 public:
  ChromeAppSortingDefaultOrdinalNoCollision() {}
  ~ChromeAppSortingDefaultOrdinalNoCollision() override {}

  void Verify() override {
    // Use the default page.
    EXPECT_TRUE(app_sorting()->GetPageOrdinal(app_->id()).Equals(
        default_page_ordinal_));
    // Not using the default app launch ordinal because of the collision.
    EXPECT_FALSE(app_sorting()->GetAppLaunchOrdinal(app_->id()).Equals(
        default_app_launch_ordinal_));
  }

 protected:
  void SetupUserOrdinals() override {
    other_app_ = prefs_.AddApp("other_app");
    // Creates a collision.
    app_sorting()->SetPageOrdinal(other_app_->id(), default_page_ordinal_);
    app_sorting()->SetAppLaunchOrdinal(other_app_->id(),
                                       default_app_launch_ordinal_);

    yet_another_app_ = prefs_.AddApp("yet_aother_app");
    app_sorting()->SetPageOrdinal(yet_another_app_->id(),
                                  default_page_ordinal_);
    app_sorting()->SetAppLaunchOrdinal(yet_another_app_->id(),
                                       default_app_launch_ordinal_);
  }

 private:
  scoped_refptr<Extension> other_app_;
  scoped_refptr<Extension> yet_another_app_;
};
TEST_F(ChromeAppSortingDefaultOrdinalNoCollision,
       ChromeAppSortingDefaultOrdinalNoCollision) {}

// Tests that SetExtensionVisible() correctly hides and unhides extensions.
class ChromeAppSortingSetExtensionVisible : public ExtensionPrefsTest {
 public:
  ChromeAppSortingSetExtensionVisible() {}
  ~ChromeAppSortingSetExtensionVisible() override {}

  void Initialize() override {
    first_app_ = prefs_.AddApp("first_app");
    second_app_ = prefs_.AddApp("second_app");
  }

  void Verify() override {
    ChromeAppSorting* sorting = app_sorting();
    syncer::StringOrdinal page1 = sorting->GetPageOrdinal(first_app_->id());
    syncer::StringOrdinal page2 = sorting->GetPageOrdinal(second_app_->id());
    EXPECT_TRUE(sorting->GetAppLaunchOrdinal(first_app_->id()).IsValid());
    EXPECT_TRUE(sorting->GetAppLaunchOrdinal(second_app_->id()).IsValid());
    EXPECT_TRUE(page1.IsValid());
    EXPECT_TRUE(page2.IsValid());
    EXPECT_TRUE(page1.Equals(page2));

    sorting->SetExtensionVisible(first_app_->id(), false);
    EXPECT_EQ(
        1U, sorting->CountItemsVisibleOnNtp(sorting->ntp_ordinal_map_[page1]));

    sorting->SetExtensionVisible(first_app_->id(), true);
    EXPECT_EQ(
        2U, sorting->CountItemsVisibleOnNtp(sorting->ntp_ordinal_map_[page1]));
  }

 private:
  scoped_refptr<Extension> first_app_;
  scoped_refptr<Extension> second_app_;
};
TEST_F(ChromeAppSortingSetExtensionVisible,
       ChromeAppSortingSetExtensionVisible) {
}

}  // namespace extensions
