15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/native_backend_gnome_x.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/autofill/core/common/password_form.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/password_manager/core/browser/psl_matching_helper.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/password_manager/core/common/password_manager_pref_names.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using autofill::PasswordForm;
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UTF8ToUTF16;
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UTF16ToUTF8;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using password_manager::PasswordStoreChange;
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using password_manager::PasswordStoreChangeList;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// What follows is a very simple implementation of the subset of the GNOME
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Keyring API that we actually use. It gets substituted for the real one by
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MockGnomeKeyringLoader, which hooks into the facility normally used to load
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the GNOME Keyring library at runtime to avoid a static dependency on it.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MockKeyringItem {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockKeyringItem() {}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockKeyringItem(const char* keyring,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const std::string& display_name,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const std::string& password)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : keyring(keyring ? keyring : "login"),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      display_name(display_name),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      password(password) {}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ItemAttribute {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ItemAttribute() : type(UINT32), value_uint32(0) {}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    explicit ItemAttribute(uint32_t value)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : type(UINT32), value_uint32(value) {}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    explicit ItemAttribute(const std::string& value)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : type(STRING), value_string(value) {}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool Equals(const ItemAttribute& x) const {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (type != x.type) return false;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return (type == STRING) ? value_string == x.value_string
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              : value_uint32 == x.value_uint32;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum Type { UINT32, STRING } type;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t value_uint32;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string value_string;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<std::string, ItemAttribute> attribute_map;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<std::pair<std::string, ItemAttribute> > attribute_query;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Matches(const attribute_query& query) const {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The real GNOME Keyring doesn't match empty queries.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (query.empty()) return false;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < query.size(); ++i) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attribute_map::const_iterator match = attributes.find(query[i].first);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (match == attributes.end()) return false;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!match->second.Equals(query[i].second)) return false;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string keyring;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string display_name;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string password;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attribute_map attributes;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The list of all keyring items we have stored.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<MockKeyringItem> mock_keyring_items;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool mock_keyring_reject_local_ids = false;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsStringAttribute(const GnomeKeyringPasswordSchema* schema,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const std::string& name) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; schema->attributes[i].name; ++i)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name == schema->attributes[i].name)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return schema->attributes[i].type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED() << "Requested type of nonexistent attribute";
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gboolean mock_gnome_keyring_is_available() {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gpointer mock_gnome_keyring_store_password(
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GnomeKeyringPasswordSchema* schema,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gchar* keyring,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gchar* display_name,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gchar* password,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GnomeKeyringOperationDoneCallback callback,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gpointer data,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GDestroyNotify destroy_data,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ...) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_keyring_items.push_back(
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockKeyringItem(keyring, display_name, password));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockKeyringItem* item = &mock_keyring_items.back();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string keyring_desc =
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keyring ? base::StringPrintf("keyring %s", keyring)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              : std::string("default keyring");
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "Adding item with origin " << display_name
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << " to " << keyring_desc;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_list ap;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_start(ap, destroy_data);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* name;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while ((name = va_arg(ap, gchar*))) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsStringAttribute(schema, name)) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      item->attributes[name] =
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          MockKeyringItem::ItemAttribute(va_arg(ap, gchar*));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG(1) << "Adding item attribute " << name
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              << ", value '" << item->attributes[name].value_string << "'";
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      item->attributes[name] =
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          MockKeyringItem::ItemAttribute(va_arg(ap, uint32_t));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG(1) << "Adding item attribute " << name
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              << ", value " << item->attributes[name].value_uint32;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_end(ap);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As a hack to ease testing migration, make it possible to reject the new
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // format for the app string. This way we can add them easily to migrate.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mock_keyring_reject_local_ids) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockKeyringItem::attribute_map::iterator it =
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item->attributes.find("application");
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it != item->attributes.end() &&
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        it->second.type == MockKeyringItem::ItemAttribute::STRING &&
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::StringPiece(it->second.value_string).starts_with("chrome-")) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mock_keyring_items.pop_back();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // GnomeKeyringResult, data
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback(GNOME_KEYRING_RESULT_IO_ERROR, data);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GnomeKeyringResult, data
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback(GNOME_KEYRING_RESULT_OK, data);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gpointer mock_gnome_keyring_delete_password(
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GnomeKeyringPasswordSchema* schema,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GnomeKeyringOperationDoneCallback callback,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gpointer data,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GDestroyNotify destroy_data,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ...) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockKeyringItem::attribute_query query;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_list ap;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_start(ap, destroy_data);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* name;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while ((name = va_arg(ap, gchar*))) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsStringAttribute(schema, name)) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      query.push_back(make_pair(std::string(name),
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          MockKeyringItem::ItemAttribute(va_arg(ap, gchar*))));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG(1) << "Querying with item attribute " << name
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              << ", value '" << query.back().second.value_string << "'";
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      query.push_back(make_pair(std::string(name),
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          MockKeyringItem::ItemAttribute(va_arg(ap, uint32_t))));
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG(1) << "Querying with item attribute " << name
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              << ", value " << query.back().second.value_uint32;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_end(ap);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool deleted = false;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = mock_keyring_items.size(); i > 0; --i) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockKeyringItem* item = &mock_keyring_items[i - 1];
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (item->Matches(query)) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG(1) << "Deleting item with origin " <<  item->display_name;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mock_keyring_items.erase(mock_keyring_items.begin() + (i - 1));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      deleted = true;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GnomeKeyringResult, data
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback(deleted ? GNOME_KEYRING_RESULT_OK
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   : GNOME_KEYRING_RESULT_NO_MATCH, data);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gpointer mock_gnome_keyring_find_items(
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GnomeKeyringItemType type,
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GnomeKeyringAttributeList* attributes,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GnomeKeyringOperationGetListCallback callback,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gpointer data,
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GDestroyNotify destroy_data) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockKeyringItem::attribute_query query;
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < attributes->len; ++i) {
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GnomeKeyringAttribute attribute =
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        g_array_index(attributes, GnomeKeyringAttribute, i);
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (attribute.type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) {
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      query.push_back(
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          make_pair(std::string(attribute.name),
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    MockKeyringItem::ItemAttribute(attribute.value.string)));
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      VLOG(1) << "Querying with item attribute " << attribute.name
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              << ", value '" << query.back().second.value_string << "'";
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      query.push_back(
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          make_pair(std::string(attribute.name),
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    MockKeyringItem::ItemAttribute(attribute.value.integer)));
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      VLOG(1) << "Querying with item attribute " << attribute.name << ", value "
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              << query.back().second.value_uint32;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find matches and add them to a list of results.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GList* results = NULL;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < mock_keyring_items.size(); ++i) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockKeyringItem* item = &mock_keyring_items[i];
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (item->Matches(query)) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GnomeKeyringFound* found = new GnomeKeyringFound;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found->keyring = strdup(item->keyring.c_str());
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found->item_id = i;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found->attributes = gnome_keyring_attribute_list_new();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (MockKeyringItem::attribute_map::const_iterator it =
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               item->attributes.begin();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           it != item->attributes.end();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           ++it) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (it->second.type == MockKeyringItem::ItemAttribute::STRING) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          gnome_keyring_attribute_list_append_string(
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              found->attributes, it->first.c_str(),
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              it->second.value_string.c_str());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          gnome_keyring_attribute_list_append_uint32(
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              found->attributes, it->first.c_str(),
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              it->second.value_uint32);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found->secret = strdup(item->password.c_str());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      results = g_list_prepend(results, found);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GnomeKeyringResult, GList*, data
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback(results ? GNOME_KEYRING_RESULT_OK
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   : GNOME_KEYRING_RESULT_NO_MATCH, results, data);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now free the list of results.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GList* element = g_list_first(results);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (element) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GnomeKeyringFound* found = static_cast<GnomeKeyringFound*>(element->data);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    free(found->keyring);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gnome_keyring_attribute_list_free(found->attributes);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    free(found->secret);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete found;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    element = g_list_next(element);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_list_free(results);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gchar* mock_gnome_keyring_result_to_message(GnomeKeyringResult res) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return "mock keyring simulating failure";
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Inherit to get access to protected fields.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockGnomeKeyringLoader : public GnomeKeyringLoader {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool LoadMockGnomeKeyring() {
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!LoadGnomeKeyring())
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GNOME_KEYRING_ASSIGN_POINTER(name) \
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gnome_keyring_##name = &mock_gnome_keyring_##name;
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GNOME_KEYRING_FOR_EACH_MOCKED_FUNC(GNOME_KEYRING_ASSIGN_POINTER)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef GNOME_KEYRING_ASSIGN_POINTER
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyring_loaded = true;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Reset the state of the mock library.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_keyring_items.clear();
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_keyring_reject_local_ids = false;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void CheckPasswordChanges(const PasswordStoreChangeList& expected_list,
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          const PasswordStoreChangeList& actual_list) {
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(expected_list.size(), actual_list.size());
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < expected_list.size(); ++i) {
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected_list[i].type(), actual_list[i].type());
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PasswordForm& expected = expected_list[i].form();
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const PasswordForm& actual = actual_list[i].form();
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.origin, actual.origin);
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.password_value, actual.password_value);
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.action, actual.action);
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.username_element, actual.username_element);
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.username_value, actual.username_value);
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.password_element, actual.password_element);
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.submit_element, actual.submit_element);
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.signon_realm, actual.signon_realm);
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.ssl_valid, actual.ssl_valid);
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.preferred, actual.preferred);
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // We don't check the date created. It varies due to bug in the
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // serialization. Integer seconds are saved instead of microseconds.
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.blacklisted_by_user, actual.blacklisted_by_user);
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.type, actual.type);
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.times_used, actual.times_used);
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(expected.scheme, actual.scheme);
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(expected.date_synced, actual.date_synced);
30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(expected.display_name, actual.display_name);
31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(expected.avatar_url, actual.avatar_url);
31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(expected.federation_url, actual.federation_url);
31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(expected.is_zero_click, actual.is_zero_click);
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void CheckPasswordChangesWithResult(const PasswordStoreChangeList* expected,
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    const PasswordStoreChangeList* actual,
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    bool result) {
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(result);
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPasswordChanges(*expected, *actual);
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // anonymous namespace
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NativeBackendGnomeTest : public testing::Test {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  enum UpdateType {  // Used in CheckPSLUpdate().
3285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    UPDATE_BY_UPDATELOGIN,
3295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    UPDATE_BY_ADDLOGIN,
3305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  };
3316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  enum RemoveBetweenMethod {  // Used in CheckRemoveLoginsBetween().
3326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    CREATED,
3336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    SYNCED,
3346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  };
3355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NativeBackendGnomeTest()
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ui_thread_(BrowserThread::UI, &message_loop_),
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        db_thread_(BrowserThread::DB) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(db_thread_.Start());
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(MockGnomeKeyringLoader::LoadMockGnomeKeyring());
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_google_.origin = GURL("http://www.google.com/");
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_google_.action = GURL("http://www.google.com/login");
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_google_.username_element = UTF8ToUTF16("user");
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_google_.username_value = UTF8ToUTF16("joeschmoe");
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_google_.password_element = UTF8ToUTF16("pass");
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_google_.password_value = UTF8ToUTF16("seekrit");
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_google_.submit_element = UTF8ToUTF16("submit");
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    form_google_.signon_realm = "http://www.google.com/";
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    form_google_.type = PasswordForm::TYPE_GENERATED;
355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    form_google_.date_created = base::Time::Now();
356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    form_google_.date_synced = base::Time::Now();
35703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    form_google_.display_name = UTF8ToUTF16("Joe Schmoe");
35803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    form_google_.avatar_url = GURL("http://www.google.com/avatar");
35903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    form_google_.federation_url = GURL("http://www.google.com/federation_url");
36003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    form_google_.is_zero_click = true;
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    form_facebook_.origin = GURL("http://www.facebook.com/");
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    form_facebook_.action = GURL("http://www.facebook.com/login");
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    form_facebook_.username_element = UTF8ToUTF16("user");
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    form_facebook_.username_value = UTF8ToUTF16("a");
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    form_facebook_.password_element = UTF8ToUTF16("password");
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    form_facebook_.password_value = UTF8ToUTF16("b");
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    form_facebook_.submit_element = UTF8ToUTF16("submit");
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    form_facebook_.signon_realm = "http://www.facebook.com/";
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    form_facebook_.date_created = base::Time::Now();
371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    form_facebook_.date_synced = base::Time::Now();
37203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    form_facebook_.display_name = UTF8ToUTF16("Joe Schmoe");
37303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    form_facebook_.avatar_url = GURL("http://www.facebook.com/avatar");
37403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    form_facebook_.federation_url = GURL("http://www.facebook.com/federation");
37503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    form_facebook_.is_zero_click = true;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_isc_.origin = GURL("http://www.isc.org/");
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_isc_.action = GURL("http://www.isc.org/auth");
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_isc_.username_element = UTF8ToUTF16("id");
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_isc_.username_value = UTF8ToUTF16("janedoe");
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_isc_.password_element = UTF8ToUTF16("passwd");
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_isc_.password_value = UTF8ToUTF16("ihazabukkit");
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    form_isc_.submit_element = UTF8ToUTF16("login");
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    form_isc_.signon_realm = "http://www.isc.org/";
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    form_isc_.date_created = base::Time::Now();
386f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    form_isc_.date_synced = base::Time::Now();
387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    other_auth_.origin = GURL("http://www.example.com/");
389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    other_auth_.username_value = UTF8ToUTF16("username");
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    other_auth_.password_value = UTF8ToUTF16("pass");
391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    other_auth_.signon_realm = "http://www.example.com/Realm";
392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    other_auth_.date_created = base::Time::Now();
393f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    other_auth_.date_synced = base::Time::Now();
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                           base::MessageLoop::QuitClosure());
39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    db_thread_.Stop();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunBothThreads() {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First we post a message to the DB thread that will run after all other
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // messages that have been posted to the DB thread (we don't expect more
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to be posted), which posts a message to the UI thread to quit the loop.
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // That way we can run both loops and be sure that the UI thread loop will
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // quit so we can get on with the rest of the test.
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&PostQuitTask, &message_loop_));
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static void PostQuitTask(base::MessageLoop* loop) {
41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckUint32Attribute(const MockKeyringItem* item,
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const std::string& attribute,
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            uint32_t value) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockKeyringItem::attribute_map::const_iterator it =
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item->attributes.find(attribute);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_NE(item->attributes.end(), it);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it != item->attributes.end()) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(MockKeyringItem::ItemAttribute::UINT32, it->second.type);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(value, it->second.value_uint32);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckStringAttribute(const MockKeyringItem* item,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const std::string& attribute,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const std::string& value) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockKeyringItem::attribute_map::const_iterator it =
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item->attributes.find(attribute);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_NE(item->attributes.end(), it);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it != item->attributes.end()) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(MockKeyringItem::ItemAttribute::STRING, it->second.type);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(value, it->second.value_string);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckMockKeyringItem(const MockKeyringItem* item,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const PasswordForm& form,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const std::string& app_string) {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We always add items to the login keyring.
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("login", item->keyring);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(form.origin.spec(), item->display_name);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(UTF16ToUTF8(form.password_value), item->password);
44903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    EXPECT_EQ(20u, item->attributes.size());
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckStringAttribute(item, "origin_url", form.origin.spec());
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckStringAttribute(item, "action_url", form.action.spec());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckStringAttribute(item, "username_element",
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         UTF16ToUTF8(form.username_element));
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckStringAttribute(item, "username_value",
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         UTF16ToUTF8(form.username_value));
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckStringAttribute(item, "password_element",
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         UTF16ToUTF8(form.password_element));
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckStringAttribute(item, "submit_element",
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         UTF16ToUTF8(form.submit_element));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckStringAttribute(item, "signon_realm", form.signon_realm);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckUint32Attribute(item, "ssl_valid", form.ssl_valid);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckUint32Attribute(item, "preferred", form.preferred);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't check the date created. It varies.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckUint32Attribute(item, "blacklisted_by_user", form.blacklisted_by_user);
465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CheckUint32Attribute(item, "type", form.type);
466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CheckUint32Attribute(item, "times_used", form.times_used);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckUint32Attribute(item, "scheme", form.scheme);
468f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    CheckStringAttribute(item, "date_synced", base::Int64ToString(
469f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        form.date_synced.ToInternalValue()));
47003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CheckStringAttribute(item, "display_name", UTF16ToUTF8(form.display_name));
47103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CheckStringAttribute(item, "avatar_url", form.avatar_url.spec());
47203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CheckStringAttribute(item, "federation_url", form.federation_url.spec());
47303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CheckUint32Attribute(item, "is_zero_click", form.is_zero_click);
47403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    CheckStringAttribute(item, "application", app_string);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Saves |credentials| and then gets logins matching |url| and |scheme|.
478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns true when something is found, and in such case copies the result to
4795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |result| when |result| is not NULL. (Note that there can be max. 1 result,
4805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // derived from |credentials|.)
4815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool CheckCredentialAvailability(const PasswordForm& credentials,
4825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   const GURL& url,
483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   const PasswordForm::Scheme& scheme,
4845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   PasswordForm* result) {
485effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    NativeBackendGnome backend(321);
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    backend.Init();
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BrowserThread::PostTask(
4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        BrowserThread::DB,
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Unretained(&backend),
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   credentials));
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PasswordForm target_form;
4965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    target_form.origin = url;
4975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    target_form.signon_realm = url.spec();
498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (scheme != PasswordForm::SCHEME_HTML) {
499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // For non-HTML forms, the realm used for authentication
500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // (http://tools.ietf.org/html/rfc1945#section-10.2) is appended to the
501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // signon_realm. Just use a default value for now.
502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      target_form.signon_realm.append("Realm");
503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      target_form.scheme = scheme;
504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::vector<PasswordForm*> form_list;
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BrowserThread::PostTask(
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        BrowserThread::DB,
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins),
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Unretained(&backend),
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   target_form,
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   &form_list));
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RunBothThreads();
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(1u, mock_keyring_items.size());
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (mock_keyring_items.size() > 0)
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CheckMockKeyringItem(&mock_keyring_items[0], credentials, "chrome-321");
519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    mock_keyring_items.clear();
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (form_list.empty())
5225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return false;
5235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(1u, form_list.size());
5245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (result)
5255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      *result = *form_list[0];
5265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    STLDeleteElements(&form_list);
5275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return true;
5285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
5295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Test that updating does not use PSL matching: Add a www.facebook.com
5315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // password, then use PSL matching to get a copy of it for m.facebook.com, and
5325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // add that copy as well. Now update the www.facebook.com password -- the
5335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // m.facebook.com password should not get updated. Depending on the argument,
5345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // the credential update is done via UpdateLogin or AddLogin.
5355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void CheckPSLUpdate(UpdateType update_type) {
5365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    NativeBackendGnome backend(321);
5375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    backend.Init();
5385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Add |form_facebook_| to saved logins.
5405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    BrowserThread::PostTask(
5415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        BrowserThread::DB,
5425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE,
5435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
5445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   base::Unretained(&backend),
5455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   form_facebook_));
5465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Get the PSL-matched copy of the saved login for m.facebook.
5485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const GURL kMobileURL("http://m.facebook.com/");
5495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    PasswordForm m_facebook_lookup;
5505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    m_facebook_lookup.origin = kMobileURL;
5515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    m_facebook_lookup.signon_realm = kMobileURL.spec();
5525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::vector<PasswordForm*> form_list;
5535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    BrowserThread::PostTask(
5545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        BrowserThread::DB,
5555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE,
5565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins),
5575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   base::Unretained(&backend),
5585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   m_facebook_lookup,
5595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   &form_list));
5605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunBothThreads();
5615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(1u, mock_keyring_items.size());
5625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(1u, form_list.size());
5635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    PasswordForm m_facebook = *form_list[0];
5645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    STLDeleteElements(&form_list);
5655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(kMobileURL, m_facebook.origin);
5665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(kMobileURL.spec(), m_facebook.signon_realm);
5675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Add the PSL-matched copy to saved logins.
5695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    BrowserThread::PostTask(
5705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        BrowserThread::DB,
5715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE,
5725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
5735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   base::Unretained(&backend),
5745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   m_facebook));
5755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunBothThreads();
5765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(2u, mock_keyring_items.size());
5775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Update www.facebook.com login.
5795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    PasswordForm new_facebook(form_facebook_);
5805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::string16 kOldPassword(form_facebook_.password_value);
5815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::string16 kNewPassword(UTF8ToUTF16("new_b"));
5825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_NE(kOldPassword, kNewPassword);
5835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    new_facebook.password_value = kNewPassword;
5845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    switch (update_type) {
5855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      case UPDATE_BY_UPDATELOGIN:
5865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        BrowserThread::PostTask(
5875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            BrowserThread::DB,
5885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            FROM_HERE,
5895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            base::Bind(base::IgnoreResult(&NativeBackendGnome::UpdateLogin),
5905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       base::Unretained(&backend),
591cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       new_facebook,
592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       base::Owned(new PasswordStoreChangeList)));
5935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        break;
5945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      case UPDATE_BY_ADDLOGIN:
5955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        BrowserThread::PostTask(
5965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            BrowserThread::DB,
5975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            FROM_HERE,
5985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
5995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       base::Unretained(&backend),
6005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                       new_facebook));
6015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        break;
6025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
6035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunBothThreads();
6055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(2u, mock_keyring_items.size());
6065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Check that m.facebook.com login was not modified by the update.
6085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    BrowserThread::PostTask(
6095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        BrowserThread::DB,
6105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE,
6115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins),
6125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   base::Unretained(&backend),
6135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   m_facebook_lookup,
6145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   &form_list));
6155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunBothThreads();
6165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // There should be two results -- the exact one, and the PSL-matched one.
6175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(2u, form_list.size());
6185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    size_t index_non_psl = 0;
6195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (!form_list[index_non_psl]->original_signon_realm.empty())
6205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      index_non_psl = 1;
6215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(kMobileURL, form_list[index_non_psl]->origin);
6225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(kMobileURL.spec(), form_list[index_non_psl]->signon_realm);
6235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(kOldPassword, form_list[index_non_psl]->password_value);
6245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    STLDeleteElements(&form_list);
6255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Check that www.facebook.com login was modified by the update.
6275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    BrowserThread::PostTask(
6285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        BrowserThread::DB,
6295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE,
6305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins),
6315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   base::Unretained(&backend),
6325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   form_facebook_,
6335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   &form_list));
6345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RunBothThreads();
6355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // There should be two results -- the exact one, and the PSL-matched one.
6365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(2u, form_list.size());
6375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    index_non_psl = 0;
6385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (!form_list[index_non_psl]->original_signon_realm.empty())
6395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      index_non_psl = 1;
6405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(form_facebook_.origin, form_list[index_non_psl]->origin);
6415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(form_facebook_.signon_realm,
6425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu              form_list[index_non_psl]->signon_realm);
6435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    EXPECT_EQ(kNewPassword, form_list[index_non_psl]->password_value);
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    STLDeleteElements(&form_list);
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void CheckMatchingWithScheme(const PasswordForm::Scheme& scheme) {
648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    other_auth_.scheme = scheme;
649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Don't match a non-HTML form with an HTML form.
651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(CheckCredentialAvailability(
652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        other_auth_, GURL("http://www.example.com"),
653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        PasswordForm::SCHEME_HTML, NULL));
654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Don't match an HTML form with non-HTML auth form.
655cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(CheckCredentialAvailability(
656cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        form_google_, GURL("http://www.google.com/"), scheme, NULL));
657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Don't match two different non-HTML auth forms with different origin.
658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_FALSE(CheckCredentialAvailability(
659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        other_auth_, GURL("http://first.example.com"), scheme, NULL));
660cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Do match non-HTML forms from the same origin.
661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(CheckCredentialAvailability(
662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        other_auth_, GURL("http://www.example.com/"), scheme, NULL));
663cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void CheckRemoveLoginsBetween(RemoveBetweenMethod date_to_test) {
6666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    NativeBackendGnome backend(42);
6676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    backend.Init();
6686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
6696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    form_google_.date_synced = base::Time();
6706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    form_isc_.date_synced = base::Time();
6716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    form_google_.date_created = base::Time();
6726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    form_isc_.date_created = base::Time();
6736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::Time now = base::Time::Now();
6746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::Time next_day = now + base::TimeDelta::FromDays(1);
6756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (date_to_test == CREATED) {
6766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      // crbug/374132. Remove the next line once it's fixed.
6776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      next_day = base::Time::FromTimeT(next_day.ToTimeT());
6786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      form_google_.date_created = now;
6796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      form_isc_.date_created = next_day;
6806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    } else {
6816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      form_google_.date_synced = now;
6826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      form_isc_.date_synced = next_day;
6836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
6846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
6856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    BrowserThread::PostTask(
6866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        BrowserThread::DB,
6876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        FROM_HERE,
6886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
6896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   base::Unretained(&backend),
6906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   form_google_));
6916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    BrowserThread::PostTask(
6926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        BrowserThread::DB,
6936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        FROM_HERE,
6946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
6956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   base::Unretained(&backend),
6966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   form_isc_));
6976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
6986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    PasswordStoreChangeList expected_changes;
6996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    expected_changes.push_back(
7006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        PasswordStoreChange(PasswordStoreChange::REMOVE, form_google_));
7016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    PasswordStoreChangeList changes;
7026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    bool (NativeBackendGnome::*method)(
7036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Time, base::Time, password_manager::PasswordStoreChangeList*) =
7046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        date_to_test == CREATED
7056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)            ? &NativeBackendGnome::RemoveLoginsCreatedBetween
7066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)            : &NativeBackendGnome::RemoveLoginsSyncedBetween;
7076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    BrowserThread::PostTaskAndReplyWithResult(
7086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        BrowserThread::DB,
7096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        FROM_HERE,
7106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(method,
7116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   base::Unretained(&backend),
7126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   base::Time(),
7136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   next_day,
7146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   &changes),
7156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(
7166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)            &CheckPasswordChangesWithResult, &expected_changes, &changes));
7176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    RunBothThreads();
7186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
7196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_EQ(1u, mock_keyring_items.size());
7206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (mock_keyring_items.size() > 0)
7216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      CheckMockKeyringItem(&mock_keyring_items[0], form_isc_, "chrome-42");
7226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
7236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Remove form_isc_.
7246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    expected_changes.clear();
7256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    expected_changes.push_back(
7266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        PasswordStoreChange(PasswordStoreChange::REMOVE, form_isc_));
7276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    BrowserThread::PostTaskAndReplyWithResult(
7286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        BrowserThread::DB,
7296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        FROM_HERE,
7306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(method,
7316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   base::Unretained(&backend),
7326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   next_day,
7336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   base::Time(),
7346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   &changes),
7356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(
7366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)            &CheckPasswordChangesWithResult, &expected_changes, &changes));
7376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    RunBothThreads();
7386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
7396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_EQ(0u, mock_keyring_items.size());
7406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
7416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
74290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoopForUI message_loop_;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestBrowserThread ui_thread_;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestBrowserThread db_thread_;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Provide some test forms to avoid having to set them up in each test.
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PasswordForm form_google_;
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PasswordForm form_facebook_;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PasswordForm form_isc_;
750cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PasswordForm other_auth_;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, BasicAddLogin) {
754effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NativeBackendGnome backend(42);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend.Init();
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&backend), form_google_));
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunBothThreads();
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, BasicListLogins) {
770effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NativeBackendGnome backend(42);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend.Init();
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(base::IgnoreResult( &NativeBackendGnome::AddLogin),
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&backend), form_google_));
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<PasswordForm*> form_list;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins),
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(&backend), &form_list));
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunBothThreads();
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Quick check that we got something back.
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, form_list.size());
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteElements(&form_list);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Save a password for www.facebook.com and see it suggested for m.facebook.com.
7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, PSLMatchingPositive) {
7985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  PasswordForm result;
7995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const GURL kMobileURL("http://m.facebook.com/");
800cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(CheckCredentialAvailability(
801cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      form_facebook_, kMobileURL, PasswordForm::SCHEME_HTML, &result));
8025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(kMobileURL, result.origin);
8035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(kMobileURL.spec(), result.signon_realm);
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Save a password for www.facebook.com and see it not suggested for
8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// m-facebook.com.
8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, PSLMatchingNegativeDomainMismatch) {
8095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(CheckCredentialAvailability(
810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      form_facebook_, GURL("http://m-facebook.com/"),
811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      PasswordForm::SCHEME_HTML, NULL));
8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test PSL matching is off for domains excluded from it.
8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, PSLMatchingDisabledDomains) {
8165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(CheckCredentialAvailability(
817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      form_google_, GURL("http://one.google.com/"),
818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      PasswordForm::SCHEME_HTML, NULL));
819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Make sure PSL matches aren't available for non-HTML forms.
822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, PSLMatchingDisabledForNonHTMLForms) {
823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CheckMatchingWithScheme(PasswordForm::SCHEME_BASIC);
824cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CheckMatchingWithScheme(PasswordForm::SCHEME_DIGEST);
825cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CheckMatchingWithScheme(PasswordForm::SCHEME_OTHER);
826cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
8275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
8285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
8295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(NativeBackendGnomeTest, PSLUpdatingStrictUpdateLogin) {
8305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CheckPSLUpdate(UPDATE_BY_UPDATELOGIN);
8315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
8325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
8335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(NativeBackendGnomeTest, PSLUpdatingStrictAddLogin) {
8345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // TODO(vabr): if AddLogin becomes no longer valid for existing logins, then
8355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // just delete this test.
8365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CheckPSLUpdate(UPDATE_BY_ADDLOGIN);
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
839a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, BasicUpdateLogin) {
840effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NativeBackendGnome backend(42);
841a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  backend.Init();
842a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
843a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // First add google login.
844a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BrowserThread::PostTask(
845a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
846a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
847a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(&backend), form_google_));
848a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
849a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RunBothThreads();
850a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
851a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PasswordForm new_form_google(form_google_);
852a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  new_form_google.times_used = 1;
853a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  new_form_google.action = GURL("http://www.google.com/different/login");
854a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
855a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
856a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
857a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
858a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
859a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Update login
860cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PasswordStoreChangeList changes;
861a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BrowserThread::PostTask(
862a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
863a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(base::IgnoreResult(&NativeBackendGnome::UpdateLogin),
864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Unretained(&backend),
865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 new_form_google,
866cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Unretained(&changes)));
867a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
868a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RunBothThreads();
869a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
870cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(1u, changes.size());
871cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(PasswordStoreChange::UPDATE, changes.front().type());
872cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(new_form_google, changes.front().form());
873a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], new_form_google, "chrome-42");
876a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
877a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, BasicRemoveLogin) {
879effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NativeBackendGnome backend(42);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend.Init();
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&backend), form_google_));
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunBothThreads();
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(base::IgnoreResult(&NativeBackendGnome::RemoveLogin),
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&backend), form_google_));
8971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunBothThreads();
8991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0u, mock_keyring_items.size());
9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
9021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Verify fix for http://crbug.com/408783.
9041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(NativeBackendGnomeTest, RemoveLoginActionMismatch) {
9051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NativeBackendGnome backend(42);
9061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  backend.Init();
9071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BrowserThread::PostTask(
9091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      BrowserThread::DB, FROM_HERE,
9101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
9111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 base::Unretained(&backend), form_google_));
9121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunBothThreads();
9141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, mock_keyring_items.size());
9161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (mock_keyring_items.size() > 0)
9171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
9181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Action url match not required for removal.
9201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  form_google_.action = GURL("https://some.other.url.com/path");
9211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BrowserThread::PostTask(
9231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      BrowserThread::DB, FROM_HERE,
9241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(base::IgnoreResult(&NativeBackendGnome::RemoveLogin),
9251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 base::Unretained(&backend), form_google_));
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunBothThreads();
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, mock_keyring_items.size());
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, RemoveNonexistentLogin) {
933effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NativeBackendGnome backend(42);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend.Init();
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First add an unrelated login.
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&backend), form_google_));
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunBothThreads();
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to remove a login that doesn't exist.
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(base::IgnoreResult(&NativeBackendGnome::RemoveLogin),
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&backend), form_isc_));
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we can still get the first form back.
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<PasswordForm*> form_list;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins),
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(&backend), &form_list));
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunBothThreads();
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Quick check that we got something back.
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, form_list.size());
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteElements(&form_list);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, UpdateNonexistentLogin) {
974effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NativeBackendGnome backend(42);
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend.Init();
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
977cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // First add an unrelated login.
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&backend), form_google_));
982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
983cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RunBothThreads();
984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
986cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
987cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
988cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
989cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Attempt to update a login that doesn't exist.
990cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PasswordStoreChangeList changes;
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
993cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(base::IgnoreResult(&NativeBackendGnome::UpdateLogin),
994cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Unretained(&backend),
995cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 form_isc_,
996cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Unretained(&changes)));
997cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
998cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RunBothThreads();
999cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1000cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(PasswordStoreChangeList(), changes);
1001cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
1002cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
1003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
1004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, AddDuplicateLogin) {
1007cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NativeBackendGnome backend(42);
1008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  backend.Init();
1009cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1010cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PasswordStoreChangeList changes;
1011cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD,
1012cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        form_google_));
1013cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
1014cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
1015cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&NativeBackendGnome::AddLogin,
1016cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Unretained(&backend), form_google_),
1017cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&CheckPasswordChanges, changes));
1018cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1019cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  changes.clear();
1020cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE,
1021cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        form_google_));
1022cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  form_google_.times_used++;
1023cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD,
1024cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        form_google_));
1025cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1026cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
1027cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
1028cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&NativeBackendGnome::AddLogin,
1029cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Unretained(&backend), form_google_),
1030cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&CheckPasswordChanges, changes));
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunBothThreads();
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, ListLoginsAppends) {
1040effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  NativeBackendGnome backend(42);
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend.Init();
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin),
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&backend), form_google_));
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send the same request twice with the same list both times.
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<PasswordForm*> form_list;
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins),
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(&backend), &form_list));
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::DB, FROM_HERE,
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins),
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(&backend), &form_list));
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunBothThreads();
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Quick check that we got two results back.
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, form_list.size());
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteElements(&form_list);
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, mock_keyring_items.size());
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mock_keyring_items.size() > 0)
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42");
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, RemoveLoginsCreatedBetween) {
10736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CheckRemoveLoginsBetween(CREATED);
10746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
1075f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
10766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(NativeBackendGnomeTest, RemoveLoginsSyncedBetween) {
10776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CheckRemoveLoginsBetween(SYNCED);
1078f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
1079f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1080effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// TODO(mdm): add more basic tests here at some point.
1081