// Copyright 2019 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 "components/password_manager/core/browser/sync/password_sync_bridge.h"

#include <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "components/password_manager/core/browser/password_store_sync.h"
#include "components/sync/model/data_batch.h"
#include "components/sync/model/entity_change.h"
#include "components/sync/model/metadata_batch.h"
#include "components/sync/model/mock_model_type_change_processor.h"
#include "components/sync/model_impl/in_memory_metadata_change_list.h"
#include "components/sync/model_impl/sync_metadata_store_change_list.h"
#include "components/sync/test/test_matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace password_manager {

namespace {

using testing::_;
using testing::Eq;
using testing::Invoke;
using testing::NotNull;
using testing::Return;
using testing::UnorderedElementsAre;

constexpr char kSignonRealm1[] = "abc";
constexpr char kSignonRealm2[] = "def";
constexpr char kSignonRealm3[] = "xyz";

// |*arg| must be of type EntityData.
MATCHER_P(EntityDataHasSignonRealm, expected_signon_realm, "") {
  return arg->specifics.password()
             .client_only_encrypted_data()
             .signon_realm() == expected_signon_realm;
}

// |*arg| must be of type PasswordForm.
MATCHER_P(FormHasSignonRealm, expected_signon_realm, "") {
  return arg.signon_realm == expected_signon_realm;
}

// |*arg| must be of type PasswordStoreChange.
MATCHER_P(ChangeHasPrimaryKey, expected_primary_key, "") {
  return arg.primary_key() == expected_primary_key;
}

// |*arg| must be of type SyncMetadataStoreChangeList.
MATCHER_P(IsSyncMetadataStoreChangeListWithStore, expected_metadata_store, "") {
  return static_cast<const syncer::SyncMetadataStoreChangeList*>(arg)
             ->GetMetadataStoreForTesting() == expected_metadata_store;
}

sync_pb::PasswordSpecifics CreateSpecifics(const std::string& origin,
                                           const std::string& username_element,
                                           const std::string& username_value,
                                           const std::string& password_element,
                                           const std::string& signon_realm) {
  sync_pb::EntitySpecifics password_specifics;
  sync_pb::PasswordSpecificsData* password_data =
      password_specifics.mutable_password()
          ->mutable_client_only_encrypted_data();
  password_data->set_origin(origin);
  password_data->set_username_element(username_element);
  password_data->set_username_value(username_value);
  password_data->set_password_element(password_element);
  password_data->set_signon_realm(signon_realm);
  return password_specifics.password();
}

sync_pb::PasswordSpecifics CreateSpecificsWithSignonRealm(
    const std::string& signon_realm) {
  return CreateSpecifics("http://www.origin.com", "username_element",
                         "username_value", "password_element", signon_realm);
}

autofill::PasswordForm MakePasswordForm(const std::string& signon_realm) {
  autofill::PasswordForm form;
  form.origin = GURL("http://www.origin.com");
  form.username_element = base::UTF8ToUTF16("username_element");
  form.username_value = base::UTF8ToUTF16("username_value");
  form.password_element = base::UTF8ToUTF16("password_element");
  form.signon_realm = signon_realm;
  return form;
}

// Creates an EntityData/EntityDataPtr around a copy of the given specifics.
syncer::EntityDataPtr SpecificsToEntity(
    const sync_pb::PasswordSpecifics& specifics) {
  syncer::EntityData data;
  // These tests do not care about the tag hash, but EntityData and friends
  // cannot differentiate between the default EntityData object if the hash
  // is unset, which causes pass/copy operations to no-op and things start to
  // break, so we throw in a junk value and forget about it.
  data.client_tag_hash = "junk";
  *data.specifics.mutable_password() = specifics;
  return data.PassToPtr();
}

// A mini database class the supports Add/Update/Remove functionality. It also
// supports an auto increment primary key that starts from 1. It will be used to
// empower the MockPasswordStoreSync be forwarding all database calls to an
// instance of this class.
class FakeDatabase {
 public:
  FakeDatabase() = default;
  ~FakeDatabase() = default;

  bool ReadAllLogins(PrimaryKeyToFormMap* map) {
    map->clear();
    for (const auto& pair : data_) {
      map->emplace(pair.first,
                   std::make_unique<autofill::PasswordForm>(*pair.second));
    }
    return true;
  }

  PasswordStoreChangeList AddLogin(const autofill::PasswordForm& form) {
    data_[primary_key_] = std::make_unique<autofill::PasswordForm>(form);
    return {
        PasswordStoreChange(PasswordStoreChange::ADD, form, primary_key_++)};
  }

  PasswordStoreChangeList AddLoginForPrimaryKey(
      int primary_key,
      const autofill::PasswordForm& form) {
    DCHECK_EQ(0U, data_.count(primary_key));
    data_[primary_key] = std::make_unique<autofill::PasswordForm>(form);
    return {PasswordStoreChange(PasswordStoreChange::ADD, form, primary_key)};
  }

  PasswordStoreChangeList UpdateLogin(const autofill::PasswordForm& form) {
    int key = GetPrimaryKey(form);
    DCHECK_NE(-1, key);
    data_[key] = std::make_unique<autofill::PasswordForm>(form);
    return {PasswordStoreChange(PasswordStoreChange::UPDATE, form, key)};
  }

  PasswordStoreChangeList RemoveLogin(int key) {
    DCHECK_NE(0U, data_.count(key));
    autofill::PasswordForm form = *data_[key];
    data_.erase(key);
    return {PasswordStoreChange(PasswordStoreChange::REMOVE, form, key)};
  }

 private:
  int GetPrimaryKey(const autofill::PasswordForm& form) const {
    for (const auto& pair : data_) {
      if (ArePasswordFormUniqueKeyEqual(*pair.second, form)) {
        return pair.first;
      }
    }
    return -1;
  }

  int primary_key_ = 1;
  PrimaryKeyToFormMap data_;

  DISALLOW_COPY_AND_ASSIGN(FakeDatabase);
};

class MockSyncMetadataStore : public PasswordStoreSync::MetadataStore {
 public:
  MockSyncMetadataStore() = default;
  ~MockSyncMetadataStore() = default;

  MOCK_METHOD0(GetAllSyncMetadata, std::unique_ptr<syncer::MetadataBatch>());
  MOCK_METHOD3(UpdateSyncMetadata,
               bool(syncer::ModelType,
                    const std::string&,
                    const sync_pb::EntityMetadata&));
  MOCK_METHOD2(ClearSyncMetadata, bool(syncer::ModelType, const std::string&));
  MOCK_METHOD2(UpdateModelTypeState,
               bool(syncer::ModelType, const sync_pb::ModelTypeState&));
  MOCK_METHOD1(ClearModelTypeState, bool(syncer::ModelType));
};

class MockPasswordStoreSync : public PasswordStoreSync {
 public:
  MockPasswordStoreSync() = default;
  ~MockPasswordStoreSync() = default;

  MOCK_METHOD1(FillAutofillableLogins,
               bool(std::vector<std::unique_ptr<autofill::PasswordForm>>*));
  MOCK_METHOD1(FillBlacklistLogins,
               bool(std::vector<std::unique_ptr<autofill::PasswordForm>>*));
  MOCK_METHOD1(ReadAllLogins, bool(PrimaryKeyToFormMap*));
  MOCK_METHOD1(RemoveLoginByPrimaryKeySync, PasswordStoreChangeList(int));
  MOCK_METHOD0(DeleteUndecryptableLogins, DatabaseCleanupResult());
  MOCK_METHOD1(AddLoginSync,
               PasswordStoreChangeList(const autofill::PasswordForm&));
  MOCK_METHOD1(UpdateLoginSync,
               PasswordStoreChangeList(const autofill::PasswordForm&));
  MOCK_METHOD1(RemoveLoginSync,
               PasswordStoreChangeList(const autofill::PasswordForm&));
  MOCK_METHOD1(NotifyLoginsChanged, void(const PasswordStoreChangeList&));
  MOCK_METHOD0(BeginTransaction, bool());
  MOCK_METHOD0(CommitTransaction, bool());
  MOCK_METHOD0(GetMetadataStore, PasswordStoreSync::MetadataStore*());
};

}  // namespace

class PasswordSyncBridgeTest : public testing::Test {
 public:
  PasswordSyncBridgeTest() {
    ON_CALL(mock_password_store_sync_, GetMetadataStore())
        .WillByDefault(testing::Return(&mock_sync_metadata_store_sync_));
    ON_CALL(mock_password_store_sync_, ReadAllLogins(_))
        .WillByDefault(Invoke(&fake_db_, &FakeDatabase::ReadAllLogins));
    ON_CALL(mock_password_store_sync_, AddLoginSync(_))
        .WillByDefault(Invoke(&fake_db_, &FakeDatabase::AddLogin));
    ON_CALL(mock_password_store_sync_, UpdateLoginSync(_))
        .WillByDefault(Invoke(&fake_db_, &FakeDatabase::UpdateLogin));
    ON_CALL(mock_password_store_sync_, RemoveLoginByPrimaryKeySync(_))
        .WillByDefault(Invoke(&fake_db_, &FakeDatabase::RemoveLogin));

    bridge_ = std::make_unique<PasswordSyncBridge>(
        mock_processor_.CreateForwardingProcessor(),
        &mock_password_store_sync_);

    // It's the responsibility of the PasswordStoreSync to inform the bridge
    // about changes in the password store. The bridge notifies the
    // PasswordStoreSync about the new changes even if they are initiated by the
    // bridge itself.
    ON_CALL(mock_password_store_sync_, NotifyLoginsChanged(_))
        .WillByDefault(
            Invoke(bridge(), &PasswordSyncBridge::ActOnPasswordStoreChanges));

    ON_CALL(mock_sync_metadata_store_sync_, GetAllSyncMetadata())
        .WillByDefault(
            []() { return std::make_unique<syncer::MetadataBatch>(); });
    ON_CALL(mock_sync_metadata_store_sync_, UpdateSyncMetadata(_, _, _))
        .WillByDefault(testing::Return(true));
    ON_CALL(mock_sync_metadata_store_sync_, ClearSyncMetadata(_, _))
        .WillByDefault(testing::Return(true));
    ON_CALL(mock_sync_metadata_store_sync_, UpdateModelTypeState(_, _))
        .WillByDefault(testing::Return(true));
    ON_CALL(mock_sync_metadata_store_sync_, ClearModelTypeState(_))
        .WillByDefault(testing::Return(true));
  }

  ~PasswordSyncBridgeTest() override {}

  base::Optional<sync_pb::PasswordSpecifics> GetDataFromBridge(
      const std::string& storage_key) {
    std::unique_ptr<syncer::DataBatch> batch;
    bridge_->GetData({storage_key},
                     base::BindLambdaForTesting(
                         [&](std::unique_ptr<syncer::DataBatch> in_batch) {
                           batch = std::move(in_batch);
                         }));
    EXPECT_THAT(batch, NotNull());
    if (!batch || !batch->HasNext()) {
      return base::nullopt;
    }
    const syncer::KeyAndData& data_pair = batch->Next();
    EXPECT_THAT(data_pair.first, Eq(storage_key));
    EXPECT_FALSE(batch->HasNext());
    return data_pair.second->specifics.password();
  }

  FakeDatabase* fake_db() { return &fake_db_; }

  PasswordSyncBridge* bridge() { return bridge_.get(); }

  syncer::MockModelTypeChangeProcessor& mock_processor() {
    return mock_processor_;
  }

  MockSyncMetadataStore* mock_sync_metadata_store_sync() {
    return &mock_sync_metadata_store_sync_;
  }

  MockPasswordStoreSync* mock_password_store_sync() {
    return &mock_password_store_sync_;
  }

 private:
  FakeDatabase fake_db_;
  testing::NiceMock<syncer::MockModelTypeChangeProcessor> mock_processor_;
  testing::NiceMock<MockSyncMetadataStore> mock_sync_metadata_store_sync_;
  testing::NiceMock<MockPasswordStoreSync> mock_password_store_sync_;
  std::unique_ptr<PasswordSyncBridge> bridge_;
};

TEST_F(PasswordSyncBridgeTest, ShouldComputeClientTagHash) {
  syncer::EntityData data;
  *data.specifics.mutable_password() =
      CreateSpecifics("http://www.origin.com", "username_element",
                      "username_value", "password_element", "signon_realm");

  EXPECT_THAT(
      bridge()->GetClientTag(data),
      Eq("http%3A//www.origin.com/"
         "|username_element|username_value|password_element|signon_realm"));
}

TEST_F(PasswordSyncBridgeTest, ShouldForwardLocalChangesToTheProcessor) {
  ON_CALL(mock_processor(), IsTrackingMetadata()).WillByDefault(Return(true));

  PasswordStoreChangeList changes;
  changes.push_back(PasswordStoreChange(
      PasswordStoreChange::ADD, MakePasswordForm(kSignonRealm1), /*id=*/1));
  changes.push_back(PasswordStoreChange(
      PasswordStoreChange::UPDATE, MakePasswordForm(kSignonRealm2), /*id=*/2));
  changes.push_back(PasswordStoreChange(
      PasswordStoreChange::REMOVE, MakePasswordForm(kSignonRealm3), /*id=*/3));
  PasswordStoreSync::MetadataStore* store =
      mock_password_store_sync()->GetMetadataStore();
  EXPECT_CALL(mock_processor(),
              Put("1", EntityDataHasSignonRealm(kSignonRealm1),
                  IsSyncMetadataStoreChangeListWithStore(store)));
  EXPECT_CALL(mock_processor(),
              Put("2", EntityDataHasSignonRealm(kSignonRealm2),
                  IsSyncMetadataStoreChangeListWithStore(store)));
  EXPECT_CALL(mock_processor(),
              Delete("3", IsSyncMetadataStoreChangeListWithStore(store)));

  bridge()->ActOnPasswordStoreChanges(changes);
}

TEST_F(PasswordSyncBridgeTest,
       ShouldNotForwardLocalChangesToTheProcessorIfSyncDisabled) {
  ON_CALL(mock_processor(), IsTrackingMetadata()).WillByDefault(Return(false));

  PasswordStoreChangeList changes;
  changes.push_back(PasswordStoreChange(
      PasswordStoreChange::ADD, MakePasswordForm(kSignonRealm1), /*id=*/1));
  changes.push_back(PasswordStoreChange(
      PasswordStoreChange::UPDATE, MakePasswordForm(kSignonRealm2), /*id=*/2));
  changes.push_back(PasswordStoreChange(
      PasswordStoreChange::REMOVE, MakePasswordForm(kSignonRealm3), /*id=*/3));

  EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
  EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);

  bridge()->ActOnPasswordStoreChanges(changes);
}

TEST_F(PasswordSyncBridgeTest, ShouldApplyEmptySyncChangesWithoutError) {
  base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
      bridge()->CreateMetadataChangeList(), syncer::EntityChangeList());
  EXPECT_FALSE(error);
}

TEST_F(PasswordSyncBridgeTest, ShouldApplyMetadataWithEmptySyncChanges) {
  const std::string kStorageKey = "1";
  const std::string kServerId = "TestServerId";
  sync_pb::EntityMetadata metadata;
  metadata.set_server_id(kServerId);
  auto metadata_change_list =
      std::make_unique<syncer::InMemoryMetadataChangeList>();
  metadata_change_list->UpdateMetadata(kStorageKey, metadata);

  EXPECT_CALL(*mock_password_store_sync(), NotifyLoginsChanged(_)).Times(0);

  EXPECT_CALL(*mock_sync_metadata_store_sync(),
              UpdateSyncMetadata(syncer::PASSWORDS, kStorageKey, _));

  base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
      std::move(metadata_change_list), syncer::EntityChangeList());
  EXPECT_FALSE(error);
}

TEST_F(PasswordSyncBridgeTest, ShouldApplyRemoteCreation) {
  ON_CALL(mock_processor(), IsTrackingMetadata()).WillByDefault(Return(true));
  // Since this remote creation is the first entry in the FakeDatabase, it will
  // be assigned a primary key 1.
  const std::string kStorageKey = "1";

  sync_pb::PasswordSpecifics specifics =
      CreateSpecificsWithSignonRealm(kSignonRealm1);

  testing::InSequence in_sequence;
  EXPECT_CALL(*mock_password_store_sync(), BeginTransaction());
  EXPECT_CALL(*mock_password_store_sync(),
              AddLoginSync(FormHasSignonRealm(kSignonRealm1)));
  EXPECT_CALL(mock_processor(), UpdateStorageKey(_, kStorageKey, _));
  EXPECT_CALL(*mock_password_store_sync(), CommitTransaction());
  EXPECT_CALL(
      *mock_password_store_sync(),
      NotifyLoginsChanged(UnorderedElementsAre(ChangeHasPrimaryKey(1))));

  // Processor shouldn't be notified about remote changes.
  EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);

  base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
      bridge()->CreateMetadataChangeList(),
      {syncer::EntityChange::CreateAdd(
          /*storage_key=*/"", SpecificsToEntity(specifics))});
  EXPECT_FALSE(error);
}

TEST_F(PasswordSyncBridgeTest, ShouldApplyRemoteUpdate) {
  const int kPrimaryKey = 1000;
  const std::string kStorageKey = "1000";
  // Add the form to the DB.
  fake_db()->AddLoginForPrimaryKey(kPrimaryKey,
                                   MakePasswordForm(kSignonRealm1));

  sync_pb::PasswordSpecifics specifics =
      CreateSpecificsWithSignonRealm(kSignonRealm1);

  testing::InSequence in_sequence;
  EXPECT_CALL(*mock_password_store_sync(), BeginTransaction());
  EXPECT_CALL(*mock_password_store_sync(),
              UpdateLoginSync(FormHasSignonRealm(kSignonRealm1)));
  EXPECT_CALL(*mock_password_store_sync(), CommitTransaction());
  EXPECT_CALL(*mock_password_store_sync(),
              NotifyLoginsChanged(
                  UnorderedElementsAre(ChangeHasPrimaryKey(kPrimaryKey))));

  // Processor shouldn't be notified about remote changes.
  EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
  EXPECT_CALL(mock_processor(), UpdateStorageKey(_, _, _)).Times(0);

  base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
      bridge()->CreateMetadataChangeList(),
      {syncer::EntityChange::CreateUpdate(kStorageKey,
                                          SpecificsToEntity(specifics))});
  EXPECT_FALSE(error);
}

TEST_F(PasswordSyncBridgeTest, ShouldApplyRemoteDeletion) {
  const int kPrimaryKey = 1000;
  const std::string kStorageKey = "1000";
  // Add the form to the DB.
  fake_db()->AddLoginForPrimaryKey(kPrimaryKey,
                                   MakePasswordForm(kSignonRealm1));

  testing::InSequence in_sequence;
  EXPECT_CALL(*mock_password_store_sync(), BeginTransaction());
  EXPECT_CALL(*mock_password_store_sync(),
              RemoveLoginByPrimaryKeySync(kPrimaryKey));
  EXPECT_CALL(*mock_password_store_sync(), CommitTransaction());
  EXPECT_CALL(*mock_password_store_sync(),
              NotifyLoginsChanged(
                  UnorderedElementsAre(ChangeHasPrimaryKey(kPrimaryKey))));

  // Processor shouldn't be notified about remote changes.
  EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);

  base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
      bridge()->CreateMetadataChangeList(),
      {syncer::EntityChange::CreateDelete(kStorageKey)});
  EXPECT_FALSE(error);
}

TEST_F(PasswordSyncBridgeTest, ShouldGetDataForStorageKey) {
  const int kPrimaryKey1 = 1000;
  const int kPrimaryKey2 = 1001;
  const std::string kPrimaryKeyStr1 = "1000";
  const std::string kPrimaryKeyStr2 = "1001";
  autofill::PasswordForm form1 = MakePasswordForm(kSignonRealm1);
  autofill::PasswordForm form2 = MakePasswordForm(kSignonRealm2);

  fake_db()->AddLoginForPrimaryKey(kPrimaryKey1, form1);
  fake_db()->AddLoginForPrimaryKey(kPrimaryKey2, form2);

  base::Optional<sync_pb::PasswordSpecifics> optional_specifics =
      GetDataFromBridge(/*storage_key=*/kPrimaryKeyStr1);
  ASSERT_TRUE(optional_specifics.has_value());
  EXPECT_EQ(
      kSignonRealm1,
      optional_specifics.value().client_only_encrypted_data().signon_realm());

  optional_specifics = GetDataFromBridge(/*storage_key=*/kPrimaryKeyStr2);
  ASSERT_TRUE(optional_specifics.has_value());
  EXPECT_EQ(kSignonRealm2,
            optional_specifics->client_only_encrypted_data().signon_realm());
}

TEST_F(PasswordSyncBridgeTest, ShouldNotGetDataForNonExistingStorageKey) {
  const std::string kPrimaryKeyStr = "1";

  base::Optional<sync_pb::PasswordSpecifics> optional_specifics =
      GetDataFromBridge(/*storage_key=*/kPrimaryKeyStr);
  EXPECT_FALSE(optional_specifics.has_value());
}

TEST_F(PasswordSyncBridgeTest, ShouldMergeSyncRemoteAndLocalPasswords) {
  ON_CALL(mock_processor(), IsTrackingMetadata()).WillByDefault(Return(true));
  // Setup the test to have Form 1 and Form 2 stored locally, and Form 2 and
  // Form 3 coming as remote changes. We will assign primary keys for Form 1 and
  // Form 2. Form 3 will arrive as remote creation, and FakeDatabase will assign
  // it primary key 1.
  const int kPrimaryKey1 = 1000;
  const int kPrimaryKey2 = 1001;
  const int kExpectedPrimaryKey3 = 1;
  const std::string kPrimaryKeyStr1 = "1000";
  const std::string kPrimaryKeyStr2 = "1001";
  const std::string kExpectedPrimaryKeyStr3 = "1";
  autofill::PasswordForm form1 = MakePasswordForm(kSignonRealm1);
  autofill::PasswordForm form2 = MakePasswordForm(kSignonRealm2);
  autofill::PasswordForm form3 = MakePasswordForm(kSignonRealm3);
  sync_pb::PasswordSpecifics specifics1 =
      CreateSpecificsWithSignonRealm(kSignonRealm1);
  sync_pb::PasswordSpecifics specifics2 =
      CreateSpecificsWithSignonRealm(kSignonRealm2);
  sync_pb::PasswordSpecifics specifics3 =
      CreateSpecificsWithSignonRealm(kSignonRealm3);

  fake_db()->AddLoginForPrimaryKey(kPrimaryKey1, form1);
  fake_db()->AddLoginForPrimaryKey(kPrimaryKey2, form2);

  // Form 1 will be added to the change processor, Form 2 will be updated in the
  // password sync store, and Form 3 will be added to the password store sync.

  // Interactions should happen in this order:
  //           +--> Put(1) ------------------------------------+
  //           |                                               |
  // Begin() --|--> UpdateLoginSync(2) --> UpdateStorageKey(2)-|--> Commit()
  //           |                                               |
  //           +--> AddLoginSync (3)   --> UpdateStorageKey(3)-+

  testing::Sequence s1, s2, s3;
  EXPECT_CALL(*mock_password_store_sync(), BeginTransaction())
      .InSequence(s1, s2, s3);
  EXPECT_CALL(mock_processor(),
              Put(kPrimaryKeyStr1, EntityDataHasSignonRealm(kSignonRealm1), _))
      .InSequence(s1);
  EXPECT_CALL(*mock_password_store_sync(),
              UpdateLoginSync(FormHasSignonRealm(kSignonRealm2)))
      .InSequence(s2);
  EXPECT_CALL(*mock_password_store_sync(),
              AddLoginSync(FormHasSignonRealm(kSignonRealm3)))
      .InSequence(s3);

  EXPECT_CALL(mock_processor(), UpdateStorageKey(_, kPrimaryKeyStr2, _))
      .InSequence(s2);
  EXPECT_CALL(mock_processor(), UpdateStorageKey(_, kExpectedPrimaryKeyStr3, _))
      .InSequence(s3);
  EXPECT_CALL(*mock_password_store_sync(), CommitTransaction())
      .InSequence(s1, s2, s3);

  EXPECT_CALL(*mock_password_store_sync(),
              NotifyLoginsChanged(UnorderedElementsAre(
                  ChangeHasPrimaryKey(kPrimaryKey2),
                  ChangeHasPrimaryKey(kExpectedPrimaryKey3))))
      .InSequence(s1, s2, s3);

  // Processor shouldn't be informed about Form 2 or Form 3.
  EXPECT_CALL(mock_processor(), Put(kPrimaryKeyStr2, _, _)).Times(0);
  EXPECT_CALL(mock_processor(), Put(kExpectedPrimaryKeyStr3, _, _)).Times(0);

  base::Optional<syncer::ModelError> error = bridge()->MergeSyncData(
      bridge()->CreateMetadataChangeList(),
      {syncer::EntityChange::CreateAdd(
           /*storage_key=*/"", SpecificsToEntity(specifics2)),
       syncer::EntityChange::CreateAdd(
           /*storage_key=*/"", SpecificsToEntity(specifics3))});
  EXPECT_FALSE(error);
}

TEST_F(PasswordSyncBridgeTest, ShouldGetAllDataForDebuggingWithHiddenPassword) {
  const int kPrimaryKey1 = 1000;
  const int kPrimaryKey2 = 1001;
  autofill::PasswordForm form1 = MakePasswordForm(kSignonRealm1);
  autofill::PasswordForm form2 = MakePasswordForm(kSignonRealm2);

  fake_db()->AddLoginForPrimaryKey(kPrimaryKey1, form1);
  fake_db()->AddLoginForPrimaryKey(kPrimaryKey2, form2);

  std::unique_ptr<syncer::DataBatch> batch;

  bridge()->GetAllDataForDebugging(base::BindLambdaForTesting(
      [&](std::unique_ptr<syncer::DataBatch> in_batch) {
        batch = std::move(in_batch);
      }));

  ASSERT_THAT(batch, NotNull());
  EXPECT_TRUE(batch->HasNext());
  while (batch->HasNext()) {
    const syncer::KeyAndData& data_pair = batch->Next();
    EXPECT_EQ("hidden", data_pair.second->specifics.password()
                            .client_only_encrypted_data()
                            .password_value());
  }
}

TEST_F(PasswordSyncBridgeTest,
       ShouldCallModelReadyUponConstructionWithMetadata) {
  ON_CALL(*mock_sync_metadata_store_sync(), GetAllSyncMetadata())
      .WillByDefault([&]() {
        sync_pb::ModelTypeState model_type_state;
        model_type_state.set_initial_sync_done(true);
        auto metadata_batch = std::make_unique<syncer::MetadataBatch>();
        metadata_batch->SetModelTypeState(model_type_state);
        metadata_batch->AddMetadata("storage_key", sync_pb::EntityMetadata());
        return metadata_batch;
      });

  EXPECT_CALL(mock_processor(), ModelReadyToSync(MetadataBatchContains(
                                    /*state=*/syncer::HasInitialSyncDone(),
                                    /*entities=*/testing::SizeIs(1))));

  PasswordSyncBridge bridge(mock_processor().CreateForwardingProcessor(),
                            mock_password_store_sync());
}

}  // namespace password_manager
