File: single_client_offer_sync_test.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (236 lines) | stat: -rw-r--r-- 9,628 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "build/build_config.h"
#include "chrome/browser/sync/test/integration/autofill_helper.h"
#include "chrome/browser/sync/test/integration/offer_helper.h"
#include "chrome/browser/sync/test/integration/sync_service_impl_harness.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/browser/sync/test/integration/wallet_helper.h"
#include "components/autofill/core/browser/data_manager/payments/payments_data_manager.h"
#include "components/autofill/core/browser/data_manager/payments/payments_data_manager_test_utils.h"
#include "components/autofill/core/browser/data_model/payments/autofill_offer_data.h"
#include "components/autofill/core/browser/test_utils/autofill_test_utils.h"
#include "components/sync/base/data_type.h"
#include "components/sync/protocol/data_type_state.pb.h"
#include "components/sync/service/sync_service.h"
#include "components/sync/test/fake_server.h"
#include "content/public/test/browser_test.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace {

using autofill::AutofillOfferData;
using autofill::PaymentsDataChangedWaiter;
using autofill::PaymentsDataManager;
using autofill::test::GetCardLinkedOfferData1;
using autofill::test::GetCardLinkedOfferData2;
using offer_helper::CreateDefaultSyncCardLinkedOffer;
using offer_helper::CreateSyncCardLinkedOffer;
using wallet_helper::GetPaymentsDataManager;
using wallet_helper::GetWalletDataTypeState;

ACTION_P(QuitMessageLoop, loop) {
  loop->Quit();
}

}  // namespace

class SingleClientOfferSyncTest : public SyncTest {
 public:
  SingleClientOfferSyncTest() : SyncTest(SINGLE_CLIENT) {}

  ~SingleClientOfferSyncTest() override = default;

  SingleClientOfferSyncTest(const SingleClientOfferSyncTest&) = delete;
  SingleClientOfferSyncTest& operator=(const SingleClientOfferSyncTest&) =
      delete;

 protected:
  void WaitForNumberOfOffers(size_t expected_count,
                             autofill::PaymentsDataManager* paydm) {
    while (paydm->GetAutofillOffers().size() != expected_count ||
           paydm->HasPendingPaymentQueries()) {
      PaymentsDataChangedWaiter(paydm).Wait();
    }
  }

  bool TriggerGetUpdatesAndWait() {
    const base::Time now = base::Time::Now();
    // Trigger a sync and wait for the new data to arrive.
    TriggerSyncForDataTypes(0, {syncer::AUTOFILL_WALLET_OFFER});
    return FullUpdateTypeProgressMarkerChecker(now, GetSyncService(0),
                                               syncer::AUTOFILL_WALLET_OFFER)
        .Wait();
  }
};

// Ensures that the offer sync type is enabled by default.
IN_PROC_BROWSER_TEST_F(SingleClientOfferSyncTest, EnabledByDefault) {
  ASSERT_TRUE(SetupSync());
  ASSERT_TRUE(GetClient(0)->service()->GetActiveDataTypes().Has(
      syncer::AUTOFILL_WALLET_OFFER));
}

// Ensures that offer data should get cleared from the database when sync is
// (temporarily) stopped, e.g. due to a persistent auth error.
//
// Excluded on Android because SyncServiceImplHarness doesn't have the ability
// to mimic sync-paused on Android due to https://crbug.com/1373448.
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(SingleClientOfferSyncTest, ClearOnSyncPaused) {
  GetFakeServer()->SetOfferData({CreateDefaultSyncCardLinkedOffer()});
  ASSERT_TRUE(SetupSync());

  autofill::PaymentsDataManager* paydm = GetPaymentsDataManager(0);
  ASSERT_NE(nullptr, paydm);
  // Make sure the offer data is in the DB.
  ASSERT_EQ(1uL, paydm->GetAutofillOffers().size());

  // Pause sync, the offer data should be gone.
  GetClient(0)->EnterSyncPausedStateForPrimaryAccount();
  WaitForNumberOfOffers(0, paydm);
  EXPECT_EQ(0uL, paydm->GetAutofillOffers().size());

  // Resume (unpause) sync, the data should come back.
  GetClient(0)->ExitSyncPausedStateForPrimaryAccount();
  // Wait until Sync restores the card and it arrives at paydm.
  WaitForNumberOfOffers(1, paydm);
  EXPECT_EQ(1uL, paydm->GetAutofillOffers().size());
}
#endif  // !BUILDFLAG(IS_ANDROID)

// ChromeOS does not sign out, so the test below does not apply.
#if !BUILDFLAG(IS_CHROMEOS)
// Offer data should get cleared from the database when the user signs out.
IN_PROC_BROWSER_TEST_F(SingleClientOfferSyncTest, ClearOnSignOut) {
  GetFakeServer()->SetOfferData({CreateDefaultSyncCardLinkedOffer()});
  ASSERT_TRUE(SetupSync());
  autofill::PaymentsDataManager* paydm = GetPaymentsDataManager(0);
  ASSERT_NE(nullptr, paydm);
  // Make sure the data & metadata is in the DB.
  ASSERT_EQ(1uL, paydm->GetAutofillOffers().size());

  // Signout, the data & metadata should be gone.
  GetClient(0)->SignOutPrimaryAccount();
  WaitForNumberOfOffers(0, paydm);
  EXPECT_EQ(0uL, paydm->GetAutofillOffers().size());
}
#endif  // !BUILDFLAG(IS_CHROMEOS)

// Offer is not using incremental updates. Make sure existing data gets
// replaced when synced down.
IN_PROC_BROWSER_TEST_F(SingleClientOfferSyncTest,
                       NewSyncDataShouldReplaceExistingData) {
  AutofillOfferData offer1 = GetCardLinkedOfferData1(/*offer_id=*/999);
  GetFakeServer()->SetOfferData({CreateSyncCardLinkedOffer(offer1)});
  ASSERT_TRUE(SetupSync());

  // Make sure the data is in the DB.
  PaymentsDataManager* paydm = GetPaymentsDataManager(0);
  ASSERT_NE(nullptr, paydm);
  std::vector<const AutofillOfferData*> offers = paydm->GetAutofillOffers();
  ASSERT_EQ(1uL, offers.size());
  EXPECT_EQ(999, offers[0]->GetOfferId());

  // Put some completely new data in the sync server.
  AutofillOfferData offer2 = GetCardLinkedOfferData2(/*offer_id=*/888);
  GetFakeServer()->SetOfferData({CreateSyncCardLinkedOffer(offer2)});
  PaymentsDataChangedWaiter(paydm).Wait();

  // Make sure only the new data is present.
  offers = paydm->GetAutofillOffers();
  ASSERT_EQ(1uL, offers.size());
  EXPECT_EQ(888, offers[0]->GetOfferId());
}

// Offer is not using incremental updates. The server either sends a non-empty
// update with deletion gc directives and with the (possibly empty) full data
// set, or (more often) an empty update.
IN_PROC_BROWSER_TEST_F(SingleClientOfferSyncTest, EmptyUpdatesAreIgnored) {
  AutofillOfferData offer1 = GetCardLinkedOfferData1(/*offer_id=*/999);
  GetFakeServer()->SetOfferData({CreateSyncCardLinkedOffer(offer1)});
  ASSERT_TRUE(SetupSync());

  // Make sure the card is in the DB.
  PaymentsDataManager* paydm = GetPaymentsDataManager(0);
  ASSERT_NE(nullptr, paydm);
  std::vector<const AutofillOfferData*> offers = paydm->GetAutofillOffers();
  ASSERT_EQ(1uL, offers.size());
  EXPECT_EQ(999, offers[0]->GetOfferId());

  // Trigger a sync and wait for the new data to arrive.
  sync_pb::DataTypeState state_before =
      GetWalletDataTypeState(syncer::AUTOFILL_WALLET_OFFER, 0);
  ASSERT_TRUE(TriggerGetUpdatesAndWait());

  // Check that the new progress marker is stored for empty updates. This is a
  // regression check for crbug.com/924447.
  sync_pb::DataTypeState state_after =
      GetWalletDataTypeState(syncer::AUTOFILL_WALLET_OFFER, 0);
  EXPECT_NE(state_before.progress_marker().token(),
            state_after.progress_marker().token());

  // Refresh the paydm to make sure we are checking its state after any
  // potential changes from sync in the DB propagate into paydm. As we don't
  // expect anything to change, we have no better specific condition to wait
  // for.
  paydm->Refresh();
  while (paydm->HasPendingPaymentQueries()) {
    PaymentsDataChangedWaiter(paydm).Wait();
  }

  // Make sure the same data is present on the client.
  offers = paydm->GetAutofillOffers();
  ASSERT_EQ(1uL, offers.size());
  EXPECT_EQ(999, offers[0]->GetOfferId());
}

// If the server sends the same offers with changed data, they should change on
// the client.
IN_PROC_BROWSER_TEST_F(SingleClientOfferSyncTest, ChangedEntityGetsUpdated) {
  AutofillOfferData offer = GetCardLinkedOfferData1(/*offer_id=*/999);
  offer.SetEligibleInstrumentIdForTesting({111111});
  GetFakeServer()->SetOfferData({CreateSyncCardLinkedOffer(offer)});
  ASSERT_TRUE(SetupSync());

  // Make sure the card is in the DB.
  PaymentsDataManager* paydm = GetPaymentsDataManager(0);
  ASSERT_NE(nullptr, paydm);
  std::vector<const AutofillOfferData*> offers = paydm->GetAutofillOffers();
  ASSERT_EQ(1uL, offers.size());
  EXPECT_EQ(999, offers[0]->GetOfferId());
  EXPECT_EQ(1U, offers[0]->GetEligibleInstrumentIds().size());

  // Update the data.
  offer.SetEligibleInstrumentIdForTesting({111111, 222222});
  GetFakeServer()->SetOfferData({CreateSyncCardLinkedOffer(offer)});
  PaymentsDataChangedWaiter(paydm).Wait();

  // Make sure the data is present on the client.
  paydm = GetPaymentsDataManager(0);
  ASSERT_NE(nullptr, paydm);
  offers = paydm->GetAutofillOffers();
  ASSERT_EQ(1uL, offers.size());
  EXPECT_EQ(999, offers[0]->GetOfferId());
  EXPECT_EQ(2U, offers[0]->GetEligibleInstrumentIds().size());
}

// Offer data should get cleared from the database when the Autofill sync type
// flag is disabled.
IN_PROC_BROWSER_TEST_F(SingleClientOfferSyncTest, ClearOnDisableWalletSync) {
  GetFakeServer()->SetOfferData({CreateDefaultSyncCardLinkedOffer()});
  ASSERT_TRUE(SetupSync());

  PaymentsDataManager* paydm = GetPaymentsDataManager(0);
  ASSERT_NE(nullptr, paydm);
  // Make sure the data is in the DB.
  ASSERT_EQ(1uL, paydm->GetAutofillOffers().size());

  // Turn off payments sync, the data should be gone.
  ASSERT_TRUE(
      GetClient(0)->DisableSyncForType(syncer::UserSelectableType::kPayments));
  WaitForNumberOfOffers(0, paydm);
  EXPECT_EQ(0uL, paydm->GetAutofillOffers().size());
}