blob: e1e1fec6105ad684859a6491c6d93ee47fe7faab [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/message_loop.h"
#include "base/stl_util.h"
#include "base/string16.h"
#include "base/string_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/autofill_profile.h"
#include "chrome/browser/autofill/credit_card.h"
#include "chrome/browser/intents/default_web_intent_service.h"
#include "chrome/browser/webdata/autofill_change.h"
#include "chrome/browser/webdata/autofill_entry.h"
#include "chrome/browser/webdata/web_data_service.h"
#include "chrome/browser/webdata/web_data_service_test_util.h"
#include "chrome/browser/webdata/web_intents_table.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/form_field_data.h"
#include "chrome/test/base/thread_observer_helper.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::Time;
using base::TimeDelta;
using base::WaitableEvent;
using content::BrowserThread;
using testing::_;
using testing::DoDefault;
using testing::ElementsAreArray;
using testing::Pointee;
using testing::Property;
using webkit_glue::WebIntentServiceData;
typedef std::vector<AutofillChange> AutofillChangeList;
static const int kWebDataServiceTimeoutSeconds = 8;
ACTION_P(SignalEvent, event) {
event->Signal();
}
class AutofillDBThreadObserverHelper : public DBThreadObserverHelper {
protected:
virtual ~AutofillDBThreadObserverHelper() {}
virtual void RegisterObservers() OVERRIDE {
registrar_.Add(&observer_,
chrome::NOTIFICATION_AUTOFILL_ENTRIES_CHANGED,
content::NotificationService::AllSources());
registrar_.Add(&observer_,
chrome::NOTIFICATION_AUTOFILL_PROFILE_CHANGED,
content::NotificationService::AllSources());
registrar_.Add(&observer_,
chrome::NOTIFICATION_AUTOFILL_CREDIT_CARD_CHANGED,
content::NotificationService::AllSources());
}
};
class WebDataServiceTest : public testing::Test {
public:
WebDataServiceTest()
: ui_thread_(BrowserThread::UI, &message_loop_),
db_thread_(BrowserThread::DB) {}
protected:
virtual void SetUp() {
db_thread_.Start();
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
wds_ = new WebDataService();
wds_->Init(temp_dir_.path());
}
virtual void TearDown() {
wds_->ShutdownOnUIThread();
wds_ = NULL;
base::WaitableEvent done(false, false);
BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done)));
done.Wait();
db_thread_.Stop();
MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
MessageLoop::current()->Run();
}
MessageLoopForUI message_loop_;
content::TestBrowserThread ui_thread_;
content::TestBrowserThread db_thread_;
base::FilePath profile_dir_;
scoped_refptr<WebDataService> wds_;
base::ScopedTempDir temp_dir_;
};
class WebDataServiceAutofillTest : public WebDataServiceTest {
public:
WebDataServiceAutofillTest()
: WebDataServiceTest(),
unique_id1_(1),
unique_id2_(2),
test_timeout_(TimeDelta::FromSeconds(kWebDataServiceTimeoutSeconds)),
done_event_(false, false) {}
protected:
virtual void SetUp() {
WebDataServiceTest::SetUp();
name1_ = ASCIIToUTF16("name1");
name2_ = ASCIIToUTF16("name2");
value1_ = ASCIIToUTF16("value1");
value2_ = ASCIIToUTF16("value2");
observer_helper_ = new AutofillDBThreadObserverHelper();
observer_helper_->Init();
}
virtual void TearDown() {
// Release this first so it can get destructed on the db thread.
observer_helper_ = NULL;
WebDataServiceTest::TearDown();
}
void AppendFormField(const string16& name,
const string16& value,
std::vector<FormFieldData>* form_fields) {
FormFieldData field;
field.name = name;
field.value = value;
form_fields->push_back(field);
}
string16 name1_;
string16 name2_;
string16 value1_;
string16 value2_;
int unique_id1_, unique_id2_;
const TimeDelta test_timeout_;
scoped_refptr<AutofillDBThreadObserverHelper> observer_helper_;
WaitableEvent done_event_;
};
// Run the current message loop. OnWebDataServiceRequestDone will invoke
// MessageLoop::Quit on completion, so this call will finish at that point.
static void WaitUntilCalled() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
MessageLoop::current()->Run();
}
// Simple consumer for WebIntents service data. Stores the result data and
// quits UI message loop when callback is invoked.
class WebIntentsConsumer : public WebDataServiceConsumer {
public:
virtual void OnWebDataServiceRequestDone(
WebDataService::Handle h,
const WDTypedResult* result) OVERRIDE {
services_.clear();
if (result) {
DCHECK(result->GetType() == WEB_INTENTS_RESULT);
services_ = static_cast<
const WDResult<std::vector<WebIntentServiceData> >*>(result)->
GetValue();
}
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
MessageLoop::current()->Quit();
}
// Result data from completion callback.
std::vector<WebIntentServiceData> services_;
};
// Simple consumer for WebIntents defaults data. Stores the result data and
// quits UI message loop when callback is invoked.
class WebIntentsDefaultsConsumer : public WebDataServiceConsumer {
public:
virtual void OnWebDataServiceRequestDone(
WebDataService::Handle h,
const WDTypedResult* result) OVERRIDE {
services_.clear();
if (result) {
DCHECK(result->GetType() == WEB_INTENTS_DEFAULTS_RESULT);
services_ = static_cast<
const WDResult<std::vector<DefaultWebIntentService> >*>(result)->
GetValue();
}
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
MessageLoop::current()->Quit();
}
// Result data from completion callback.
std::vector<DefaultWebIntentService> services_;
};
// Simple consumer for Keywords data. Stores the result data and quits UI
// message loop when callback is invoked.
class KeywordsConsumer : public WebDataServiceConsumer {
public:
KeywordsConsumer() : load_succeeded(false) {}
virtual void OnWebDataServiceRequestDone(
WebDataService::Handle h,
const WDTypedResult* result) OVERRIDE {
if (result) {
load_succeeded = true;
DCHECK(result->GetType() == KEYWORDS_RESULT);
keywords_result =
reinterpret_cast<const WDResult<WDKeywordsResult>*>(
result)->GetValue();
}
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
MessageLoop::current()->Quit();
}
// True if keywords data was loaded successfully.
bool load_succeeded;
// Result data from completion callback.
WDKeywordsResult keywords_result;
};
TEST_F(WebDataServiceAutofillTest, FormFillAdd) {
const AutofillChange expected_changes[] = {
AutofillChange(AutofillChange::ADD, AutofillKey(name1_, value1_)),
AutofillChange(AutofillChange::ADD, AutofillKey(name2_, value2_))
};
// This will verify that the correct notification is triggered,
// passing the correct list of autofill keys in the details.
EXPECT_CALL(
*observer_helper_->observer(),
Observe(int(chrome::NOTIFICATION_AUTOFILL_ENTRIES_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillChangeList>::ptr,
Pointee(ElementsAreArray(expected_changes))))).
WillOnce(SignalEvent(&done_event_));
std::vector<FormFieldData> form_fields;
AppendFormField(name1_, value1_, &form_fields);
AppendFormField(name2_, value2_, &form_fields);
wds_->AddFormFields(form_fields);
// The event will be signaled when the mock observer is notified.
done_event_.TimedWait(test_timeout_);
AutofillWebDataServiceConsumer<std::vector<string16> > consumer;
WebDataService::Handle handle;
static const int limit = 10;
handle = wds_->GetFormValuesForElementName(
name1_, string16(), limit, &consumer);
// The message loop will exit when the consumer is called.
MessageLoop::current()->Run();
EXPECT_EQ(handle, consumer.handle());
ASSERT_EQ(1U, consumer.result().size());
EXPECT_EQ(value1_, consumer.result()[0]);
}
TEST_F(WebDataServiceAutofillTest, FormFillRemoveOne) {
// First add some values to autofill.
EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)).
WillOnce(SignalEvent(&done_event_));
std::vector<FormFieldData> form_fields;
AppendFormField(name1_, value1_, &form_fields);
wds_->AddFormFields(form_fields);
// The event will be signaled when the mock observer is notified.
done_event_.TimedWait(test_timeout_);
// This will verify that the correct notification is triggered,
// passing the correct list of autofill keys in the details.
const AutofillChange expected_changes[] = {
AutofillChange(AutofillChange::REMOVE, AutofillKey(name1_, value1_))
};
EXPECT_CALL(
*observer_helper_->observer(),
Observe(int(chrome::NOTIFICATION_AUTOFILL_ENTRIES_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillChangeList>::ptr,
Pointee(ElementsAreArray(expected_changes))))).
WillOnce(SignalEvent(&done_event_));
wds_->RemoveFormValueForElementName(name1_, value1_);
// The event will be signaled when the mock observer is notified.
done_event_.TimedWait(test_timeout_);
}
TEST_F(WebDataServiceAutofillTest, FormFillRemoveMany) {
TimeDelta one_day(TimeDelta::FromDays(1));
Time t = Time::Now();
EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)).
WillOnce(SignalEvent(&done_event_));
std::vector<FormFieldData> form_fields;
AppendFormField(name1_, value1_, &form_fields);
AppendFormField(name2_, value2_, &form_fields);
wds_->AddFormFields(form_fields);
// The event will be signaled when the mock observer is notified.
done_event_.TimedWait(test_timeout_);
// This will verify that the correct notification is triggered,
// passing the correct list of autofill keys in the details.
const AutofillChange expected_changes[] = {
AutofillChange(AutofillChange::REMOVE, AutofillKey(name1_, value1_)),
AutofillChange(AutofillChange::REMOVE, AutofillKey(name2_, value2_))
};
EXPECT_CALL(
*observer_helper_->observer(),
Observe(int(chrome::NOTIFICATION_AUTOFILL_ENTRIES_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillChangeList>::ptr,
Pointee(ElementsAreArray(expected_changes))))).
WillOnce(SignalEvent(&done_event_));
wds_->RemoveFormElementsAddedBetween(t, t + one_day);
// The event will be signaled when the mock observer is notified.
done_event_.TimedWait(test_timeout_);
}
TEST_F(WebDataServiceAutofillTest, ProfileAdd) {
AutofillProfile profile;
// Check that GUID-based notification was sent.
const AutofillProfileChange expected_change(
AutofillProfileChange::ADD, profile.guid(), &profile);
EXPECT_CALL(
*observer_helper_->observer(),
Observe(int(chrome::NOTIFICATION_AUTOFILL_PROFILE_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillProfileChange>::ptr,
Pointee(expected_change)))).
WillOnce(SignalEvent(&done_event_));
wds_->AddAutofillProfile(profile);
done_event_.TimedWait(test_timeout_);
// Check that it was added.
AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer;
WebDataService::Handle handle = wds_->GetAutofillProfiles(&consumer);
MessageLoop::current()->Run();
EXPECT_EQ(handle, consumer.handle());
ASSERT_EQ(1U, consumer.result().size());
EXPECT_EQ(profile, *consumer.result()[0]);
STLDeleteElements(&consumer.result());
}
TEST_F(WebDataServiceAutofillTest, ProfileRemove) {
AutofillProfile profile;
// Add a profile.
EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)).
Times(1).
WillOnce(SignalEvent(&done_event_));
wds_->AddAutofillProfile(profile);
done_event_.TimedWait(test_timeout_);
// Check that it was added.
AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer;
WebDataService::Handle handle = wds_->GetAutofillProfiles(&consumer);
MessageLoop::current()->Run();
EXPECT_EQ(handle, consumer.handle());
ASSERT_EQ(1U, consumer.result().size());
EXPECT_EQ(profile, *consumer.result()[0]);
STLDeleteElements(&consumer.result());
// Check that GUID-based notification was sent.
const AutofillProfileChange expected_change(
AutofillProfileChange::REMOVE, profile.guid(), NULL);
EXPECT_CALL(
*observer_helper_->observer(),
Observe(int(chrome::NOTIFICATION_AUTOFILL_PROFILE_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillProfileChange>::ptr,
Pointee(expected_change)))).
WillOnce(SignalEvent(&done_event_));
// Remove the profile.
wds_->RemoveAutofillProfile(profile.guid());
done_event_.TimedWait(test_timeout_);
// Check that it was removed.
AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer2;
WebDataService::Handle handle2 = wds_->GetAutofillProfiles(&consumer2);
MessageLoop::current()->Run();
EXPECT_EQ(handle2, consumer2.handle());
ASSERT_EQ(0U, consumer2.result().size());
}
TEST_F(WebDataServiceAutofillTest, ProfileUpdate) {
AutofillProfile profile1;
profile1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Abe"));
AutofillProfile profile2;
profile2.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Alice"));
EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)).
WillOnce(DoDefault()).
WillOnce(SignalEvent(&done_event_));
wds_->AddAutofillProfile(profile1);
wds_->AddAutofillProfile(profile2);
done_event_.TimedWait(test_timeout_);
// Check that they were added.
AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer;
WebDataService::Handle handle = wds_->GetAutofillProfiles(&consumer);
MessageLoop::current()->Run();
EXPECT_EQ(handle, consumer.handle());
ASSERT_EQ(2U, consumer.result().size());
EXPECT_EQ(profile1, *consumer.result()[0]);
EXPECT_EQ(profile2, *consumer.result()[1]);
STLDeleteElements(&consumer.result());
AutofillProfile profile1_changed(profile1);
profile1_changed.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Bill"));
const AutofillProfileChange expected_change(
AutofillProfileChange::UPDATE, profile1.guid(), &profile1_changed);
EXPECT_CALL(
*observer_helper_->observer(),
Observe(int(chrome::NOTIFICATION_AUTOFILL_PROFILE_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillProfileChange>::ptr,
Pointee(expected_change)))).
WillOnce(SignalEvent(&done_event_));
// Update the profile.
wds_->UpdateAutofillProfile(profile1_changed);
done_event_.TimedWait(test_timeout_);
// Check that the updates were made.
AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> > consumer2;
WebDataService::Handle handle2 = wds_->GetAutofillProfiles(&consumer2);
MessageLoop::current()->Run();
EXPECT_EQ(handle2, consumer2.handle());
ASSERT_EQ(2U, consumer2.result().size());
EXPECT_NE(profile1, *consumer2.result()[0]);
EXPECT_EQ(profile1_changed, *consumer2.result()[0]);
EXPECT_EQ(profile2, *consumer2.result()[1]);
STLDeleteElements(&consumer2.result());
}
TEST_F(WebDataServiceAutofillTest, CreditAdd) {
CreditCard card;
const AutofillCreditCardChange expected_change(
AutofillCreditCardChange::ADD, card.guid(), &card);
EXPECT_CALL(
*observer_helper_->observer(),
Observe(
int(chrome::NOTIFICATION_AUTOFILL_CREDIT_CARD_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillCreditCardChange>::ptr,
Pointee(expected_change)))).
WillOnce(SignalEvent(&done_event_));
wds_->AddCreditCard(card);
done_event_.TimedWait(test_timeout_);
// Check that it was added.
AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer;
WebDataService::Handle handle = wds_->GetCreditCards(&consumer);
MessageLoop::current()->Run();
EXPECT_EQ(handle, consumer.handle());
ASSERT_EQ(1U, consumer.result().size());
EXPECT_EQ(card, *consumer.result()[0]);
STLDeleteElements(&consumer.result());
}
TEST_F(WebDataServiceAutofillTest, CreditCardRemove) {
CreditCard credit_card;
// Add a credit card.
EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)).
WillOnce(SignalEvent(&done_event_));
wds_->AddCreditCard(credit_card);
done_event_.TimedWait(test_timeout_);
// Check that it was added.
AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer;
WebDataService::Handle handle = wds_->GetCreditCards(&consumer);
MessageLoop::current()->Run();
EXPECT_EQ(handle, consumer.handle());
ASSERT_EQ(1U, consumer.result().size());
EXPECT_EQ(credit_card, *consumer.result()[0]);
STLDeleteElements(&consumer.result());
// Remove the credit card.
const AutofillCreditCardChange expected_change(
AutofillCreditCardChange::REMOVE, credit_card.guid(), NULL);
EXPECT_CALL(
*observer_helper_->observer(),
Observe(
int(chrome::NOTIFICATION_AUTOFILL_CREDIT_CARD_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillCreditCardChange>::ptr,
Pointee(expected_change)))).
WillOnce(SignalEvent(&done_event_));
wds_->RemoveCreditCard(credit_card.guid());
done_event_.TimedWait(test_timeout_);
// Check that it was removed.
AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2;
WebDataService::Handle handle2 = wds_->GetCreditCards(&consumer2);
MessageLoop::current()->Run();
EXPECT_EQ(handle2, consumer2.handle());
ASSERT_EQ(0U, consumer2.result().size());
}
TEST_F(WebDataServiceAutofillTest, CreditUpdate) {
CreditCard card1;
card1.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Abe"));
CreditCard card2;
card2.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Alice"));
EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)).
Times(2).
WillOnce(DoDefault()).
WillOnce(SignalEvent(&done_event_));
wds_->AddCreditCard(card1);
wds_->AddCreditCard(card2);
done_event_.TimedWait(test_timeout_);
// Check that they got added.
AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer;
WebDataService::Handle handle = wds_->GetCreditCards(&consumer);
MessageLoop::current()->Run();
EXPECT_EQ(handle, consumer.handle());
ASSERT_EQ(2U, consumer.result().size());
EXPECT_EQ(card1, *consumer.result()[0]);
EXPECT_EQ(card2, *consumer.result()[1]);
STLDeleteElements(&consumer.result());
CreditCard card1_changed(card1);
card1_changed.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Bill"));
const AutofillCreditCardChange expected_change(
AutofillCreditCardChange::UPDATE, card1.guid(), &card1_changed);
EXPECT_CALL(
*observer_helper_->observer(),
Observe(
int(chrome::NOTIFICATION_AUTOFILL_CREDIT_CARD_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillCreditCardChange>::ptr,
Pointee(expected_change)))).
WillOnce(SignalEvent(&done_event_));
wds_->UpdateCreditCard(card1_changed);
done_event_.TimedWait(test_timeout_);
// Check that the updates were made.
AutofillWebDataServiceConsumer<std::vector<CreditCard*> > consumer2;
WebDataService::Handle handle2 = wds_->GetCreditCards(&consumer2);
MessageLoop::current()->Run();
EXPECT_EQ(handle2, consumer2.handle());
ASSERT_EQ(2U, consumer2.result().size());
EXPECT_NE(card1, *consumer2.result()[0]);
EXPECT_EQ(card1_changed, *consumer2.result()[0]);
EXPECT_EQ(card2, *consumer2.result()[1]);
STLDeleteElements(&consumer2.result());
}
TEST_F(WebDataServiceAutofillTest, AutofillRemoveModifiedBetween) {
// Add a profile.
EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)).
Times(1).
WillOnce(SignalEvent(&done_event_));
AutofillProfile profile;
wds_->AddAutofillProfile(profile);
done_event_.TimedWait(test_timeout_);
// Check that it was added.
AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> >
profile_consumer;
WebDataService::Handle handle = wds_->GetAutofillProfiles(&profile_consumer);
MessageLoop::current()->Run();
EXPECT_EQ(handle, profile_consumer.handle());
ASSERT_EQ(1U, profile_consumer.result().size());
EXPECT_EQ(profile, *profile_consumer.result()[0]);
STLDeleteElements(&profile_consumer.result());
// Add a credit card.
EXPECT_CALL(*observer_helper_->observer(), Observe(_, _, _)).
WillOnce(SignalEvent(&done_event_));
CreditCard credit_card;
wds_->AddCreditCard(credit_card);
done_event_.TimedWait(test_timeout_);
// Check that it was added.
AutofillWebDataServiceConsumer<std::vector<CreditCard*> >
card_consumer;
handle = wds_->GetCreditCards(&card_consumer);
MessageLoop::current()->Run();
EXPECT_EQ(handle, card_consumer.handle());
ASSERT_EQ(1U, card_consumer.result().size());
EXPECT_EQ(credit_card, *card_consumer.result()[0]);
STLDeleteElements(&card_consumer.result());
// Check that GUID-based notification was sent for the profile.
const AutofillProfileChange expected_profile_change(
AutofillProfileChange::REMOVE, profile.guid(), NULL);
EXPECT_CALL(
*observer_helper_->observer(),
Observe(int(chrome::NOTIFICATION_AUTOFILL_PROFILE_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillProfileChange>::ptr,
Pointee(expected_profile_change)))).
WillOnce(SignalEvent(&done_event_));
// Check that GUID-based notification was sent for the credit card.
const AutofillCreditCardChange expected_card_change(
AutofillCreditCardChange::REMOVE, credit_card.guid(), NULL);
EXPECT_CALL(
*observer_helper_->observer(),
Observe(
int(chrome::NOTIFICATION_AUTOFILL_CREDIT_CARD_CHANGED),
content::Source<WebDataService>(wds_.get()),
Property(&content::Details<const AutofillCreditCardChange>::ptr,
Pointee(expected_card_change)))).
WillOnce(SignalEvent(&done_event_));
// Remove the profile using time range of "all time".
wds_->RemoveAutofillProfilesAndCreditCardsModifiedBetween(Time(), Time());
done_event_.TimedWait(test_timeout_);
done_event_.TimedWait(test_timeout_);
// Check that the profile was removed.
AutofillWebDataServiceConsumer<std::vector<AutofillProfile*> >
profile_consumer2;
WebDataService::Handle handle2 =
wds_->GetAutofillProfiles(&profile_consumer2);
MessageLoop::current()->Run();
EXPECT_EQ(handle2, profile_consumer2.handle());
ASSERT_EQ(0U, profile_consumer2.result().size());
// Check that the credit card was removed.
AutofillWebDataServiceConsumer<std::vector<CreditCard*> >
card_consumer2;
handle2 = wds_->GetCreditCards(&card_consumer2);
MessageLoop::current()->Run();
EXPECT_EQ(handle2, card_consumer2.handle());
ASSERT_EQ(0U, card_consumer2.result().size());
}
TEST_F(WebDataServiceTest, WebIntents) {
WebIntentsConsumer consumer;
wds_->GetWebIntentServicesForAction(ASCIIToUTF16("share"), &consumer);
WaitUntilCalled();
EXPECT_EQ(0U, consumer.services_.size());
WebIntentServiceData service;
service.service_url = GURL("http://google.com");
service.action = ASCIIToUTF16("share1");
service.type = ASCIIToUTF16("image/*");
wds_->AddWebIntentService(service);
service.action = ASCIIToUTF16("share");
service.type = ASCIIToUTF16("image/*");
wds_->AddWebIntentService(service);
service.type = ASCIIToUTF16("video/*");
wds_->AddWebIntentService(service);
wds_->GetWebIntentServicesForAction(ASCIIToUTF16("share"), &consumer);
WaitUntilCalled();
ASSERT_EQ(2U, consumer.services_.size());
if (consumer.services_[0].type != ASCIIToUTF16("image/*"))
std::swap(consumer.services_[0], consumer.services_[1]);
EXPECT_EQ(service.service_url, consumer.services_[0].service_url);
EXPECT_EQ(service.action, consumer.services_[0].action);
EXPECT_EQ(ASCIIToUTF16("image/*"), consumer.services_[0].type);
EXPECT_EQ(service.service_url, consumer.services_[1].service_url);
EXPECT_EQ(service.action, consumer.services_[1].action);
EXPECT_EQ(service.type, consumer.services_[1].type);
service.type = ASCIIToUTF16("image/*");
wds_->RemoveWebIntentService(service);
wds_->GetWebIntentServicesForAction(ASCIIToUTF16("share"), &consumer);
WaitUntilCalled();
ASSERT_EQ(1U, consumer.services_.size());
service.type = ASCIIToUTF16("video/*");
EXPECT_EQ(service.service_url, consumer.services_[0].service_url);
EXPECT_EQ(service.action, consumer.services_[0].action);
EXPECT_EQ(service.type, consumer.services_[0].type);
}
TEST_F(WebDataServiceTest, WebIntentsForURL) {
WebIntentsConsumer consumer;
WebIntentServiceData service;
service.service_url = GURL("http://google.com");
service.action = ASCIIToUTF16("share1");
service.type = ASCIIToUTF16("image/*");
wds_->AddWebIntentService(service);
service.action = ASCIIToUTF16("share");
service.type = ASCIIToUTF16("image/*");
wds_->AddWebIntentService(service);
wds_->GetWebIntentServicesForURL(
UTF8ToUTF16(service.service_url.spec()),
&consumer);
WaitUntilCalled();
ASSERT_EQ(2U, consumer.services_.size());
EXPECT_EQ(service, consumer.services_[0]);
service.action = ASCIIToUTF16("share1");
EXPECT_EQ(service, consumer.services_[1]);
}
TEST_F(WebDataServiceTest, WebIntentsGetAll) {
WebIntentsConsumer consumer;
WebIntentServiceData service;
service.service_url = GURL("http://google.com");
service.action = ASCIIToUTF16("share");
service.type = ASCIIToUTF16("image/*");
wds_->AddWebIntentService(service);
service.action = ASCIIToUTF16("edit");
wds_->AddWebIntentService(service);
wds_->GetAllWebIntentServices(&consumer);
WaitUntilCalled();
ASSERT_EQ(2U, consumer.services_.size());
if (consumer.services_[0].action != ASCIIToUTF16("edit"))
std::swap(consumer.services_[0],consumer.services_[1]);
EXPECT_EQ(service, consumer.services_[0]);
service.action = ASCIIToUTF16("share");
EXPECT_EQ(service, consumer.services_[1]);
}
TEST_F(WebDataServiceTest, WebIntentsDefaultsTest) {
WebIntentsDefaultsConsumer consumer;
wds_->GetDefaultWebIntentServicesForAction(ASCIIToUTF16("share"), &consumer);
WaitUntilCalled();
EXPECT_EQ(0U, consumer.services_.size());
DefaultWebIntentService default_service;
default_service.action = ASCIIToUTF16("share");
default_service.type = ASCIIToUTF16("type");
default_service.user_date = 1;
default_service.suppression = 4;
default_service.service_url = "service_url";
wds_->AddDefaultWebIntentService(default_service);
default_service.action = ASCIIToUTF16("share2");
default_service.service_url = "service_url_2";
wds_->AddDefaultWebIntentService(default_service);
wds_->GetDefaultWebIntentServicesForAction(ASCIIToUTF16("share"), &consumer);
WaitUntilCalled();
ASSERT_EQ(1U, consumer.services_.size());
EXPECT_EQ("service_url", consumer.services_[0].service_url);
wds_->GetAllDefaultWebIntentServices(&consumer);
WaitUntilCalled();
EXPECT_EQ(2U, consumer.services_.size());
default_service.action = ASCIIToUTF16("share");
wds_->RemoveDefaultWebIntentService(default_service);
wds_->GetDefaultWebIntentServicesForAction(ASCIIToUTF16("share"), &consumer);
WaitUntilCalled();
EXPECT_EQ(0U, consumer.services_.size());
wds_->GetDefaultWebIntentServicesForAction(ASCIIToUTF16("share2"), &consumer);
WaitUntilCalled();
ASSERT_EQ(1U, consumer.services_.size());
EXPECT_EQ("service_url_2", consumer.services_[0].service_url);
wds_->GetAllDefaultWebIntentServices(&consumer);
WaitUntilCalled();
ASSERT_EQ(1U, consumer.services_.size());
EXPECT_EQ("service_url_2", consumer.services_[0].service_url);
}
TEST_F(WebDataServiceTest, WebIntentsRemoveDefaultByServiceURL) {
WebIntentsDefaultsConsumer consumer;
GURL service_url_0("http://pandawaddle.com/observe");
GURL service_url_1("http://kittysnicker.com/mock");
DefaultWebIntentService s0;
s0.action = ASCIIToUTF16("share");
s0.type = ASCIIToUTF16("type");
s0.user_date = 1;
s0.suppression = 4;
s0.service_url = service_url_0.spec();
wds_->AddDefaultWebIntentService(s0);
DefaultWebIntentService s1;
s1.action = ASCIIToUTF16("share2");
s1.type = ASCIIToUTF16("type");
s1.user_date = 1;
s1.suppression = 4;
s1.service_url = service_url_1.spec();
wds_->AddDefaultWebIntentService(s1);
wds_->GetAllDefaultWebIntentServices(&consumer);
WaitUntilCalled();
ASSERT_EQ(2U, consumer.services_.size());
wds_->RemoveWebIntentServiceDefaults(service_url_0);
MessageLoop::current()->RunUntilIdle();
wds_->GetAllDefaultWebIntentServices(&consumer);
WaitUntilCalled();
ASSERT_EQ(1U, consumer.services_.size());
EXPECT_EQ(service_url_1.spec(), consumer.services_[0].service_url);
}