summaryrefslogtreecommitdiff
path: root/chromium/components/autofill/core/browser/geo/subkey_requester_unittest.cc
blob: 4ae481a5fa86e7bdbd73af41fd33a0e09eff5484 (plain)
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
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/autofill/core/browser/geo/subkey_requester.h"

#include <utility>

#include "base/base_paths.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
#include "third_party/libaddressinput/src/cpp/test/testdata_source.h"

namespace autofill {

namespace {

using ::i18n::addressinput::NullStorage;
using ::i18n::addressinput::Source;
using ::i18n::addressinput::Storage;
using ::i18n::addressinput::TestdataSource;

const char kLocale[] = "CA";
const char kLanguage[] = "en";
const int kInvalidSize = -1;
// For subkeys = "AB~BC~MB~NB~NL~NT~NS~NU~ON~PE~QC~SK~YT"
const int kExpectedSubkeySize = 13;
const int kEmptySize = 0;

class SubKeyReceiver : public base::RefCountedThreadSafe<SubKeyReceiver> {
 public:
  SubKeyReceiver() : subkeys_size_(kInvalidSize) {}

  void OnSubKeysReceived(const std::vector<std::string>& subkeys_codes,
                         const std::vector<std::string>& subkeys_names) {
    subkeys_size_ = subkeys_codes.size();
  }

  int subkeys_size() const { return subkeys_size_; }

 private:
  friend class base::RefCountedThreadSafe<SubKeyReceiver>;
  ~SubKeyReceiver() {}

  int subkeys_size_;

  DISALLOW_COPY_AND_ASSIGN(SubKeyReceiver);
};

// A test subclass of the SubKeyRequesterImpl. Used to simulate rules not
// being loaded.
class TestSubKeyRequester : public SubKeyRequester {
 public:
  TestSubKeyRequester(std::unique_ptr<::i18n::addressinput::Source> source,
                      std::unique_ptr<::i18n::addressinput::Storage> storage)
      : SubKeyRequester(std::move(source), std::move(storage)),
        should_load_rules_(true) {}

  ~TestSubKeyRequester() override {}

  void ShouldLoadRules(bool should_load_rules) {
    should_load_rules_ = should_load_rules;
  }

  void LoadRulesForRegion(const std::string& region_code) override {
    if (should_load_rules_) {
      SubKeyRequester::LoadRulesForRegion(region_code);
    }
  }

 private:
  bool should_load_rules_;

  DISALLOW_COPY_AND_ASSIGN(TestSubKeyRequester);
};

}  // namespace

class SubKeyRequesterTest : public testing::Test {
 protected:
  SubKeyRequesterTest() {
    base::FilePath file_path;
    CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &file_path));
    file_path = file_path.Append(FILE_PATH_LITERAL("third_party"))
                    .Append(FILE_PATH_LITERAL("libaddressinput"))
                    .Append(FILE_PATH_LITERAL("src"))
                    .Append(FILE_PATH_LITERAL("testdata"))
                    .Append(FILE_PATH_LITERAL("countryinfo.txt"));

    requester_ = std::make_unique<TestSubKeyRequester>(
        std::unique_ptr<Source>(
            new TestdataSource(true, file_path.AsUTF8Unsafe())),
        std::unique_ptr<Storage>(new NullStorage));
  }

  ~SubKeyRequesterTest() override {}

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  std::unique_ptr<TestSubKeyRequester> requester_;

 private:
  DISALLOW_COPY_AND_ASSIGN(SubKeyRequesterTest);
};

// Tests that rules are not loaded by default.
TEST_F(SubKeyRequesterTest, AreRulesLoadedForRegion_NotLoaded) {
  EXPECT_FALSE(requester_->AreRulesLoadedForRegion(kLocale));
}

// Tests that the rules are loaded correctly.
TEST_F(SubKeyRequesterTest, AreRulesLoadedForRegion_Loaded) {
  requester_->LoadRulesForRegion(kLocale);
  EXPECT_TRUE(requester_->AreRulesLoadedForRegion(kLocale));
}

// Tests that if the rules are loaded before the subkey request is started, the
// received subkeys will be returned to the delegate synchronously.
TEST_F(SubKeyRequesterTest, StartRequest_RulesLoaded) {
  scoped_refptr<SubKeyReceiver> subkey_receiver_ = new SubKeyReceiver();

  SubKeyReceiverCallback cb =
      base::BindOnce(&SubKeyReceiver::OnSubKeysReceived, subkey_receiver_);

  // Load the rules.
  requester_->LoadRulesForRegion(kLocale);
  EXPECT_TRUE(requester_->AreRulesLoadedForRegion(kLocale));

  // Start the request.
  requester_->StartRegionSubKeysRequest(kLocale, kLanguage, 0, std::move(cb));

  // Since the rules are already loaded, the subkeys should be received
  // synchronously.
  EXPECT_EQ(subkey_receiver_->subkeys_size(), kExpectedSubkeySize);
}

// Tests that if the rules are not loaded before the request and cannot be
// loaded after, the subkeys will not be received and the delegate will be
// notified.
TEST_F(SubKeyRequesterTest, StartRequest_RulesNotLoaded_WillNotLoad) {
  scoped_refptr<SubKeyReceiver> subkey_receiver_ = new SubKeyReceiver();

  SubKeyReceiverCallback cb =
      base::BindOnce(&SubKeyReceiver::OnSubKeysReceived, subkey_receiver_);

  // Make sure the rules will not be loaded in the StartRegionSubKeysRequest
  // call.
  requester_->ShouldLoadRules(false);

  // Start the normalization.
  requester_->StartRegionSubKeysRequest(kLocale, kLanguage, 0, std::move(cb));

  // Let the timeout execute.
  scoped_task_environment_.RunUntilIdle();

  // Since the rules are never loaded and the timeout is 0, the delegate should
  // get notified that the subkeys could not be received.
  EXPECT_EQ(subkey_receiver_->subkeys_size(), kEmptySize);
}

// Tests that if the rules are not loaded before the call to
// StartRegionSubKeysRequest, they will be loaded in the call.
TEST_F(SubKeyRequesterTest, StartRequest_RulesNotLoaded_WillLoad) {
  scoped_refptr<SubKeyReceiver> subkey_receiver_ = new SubKeyReceiver();

  SubKeyReceiverCallback cb =
      base::BindOnce(&SubKeyReceiver::OnSubKeysReceived, subkey_receiver_);

  // Make sure the rules will not be loaded in the StartRegionSubKeysRequest
  // call.
  requester_->ShouldLoadRules(true);
  // Start the request.
  requester_->StartRegionSubKeysRequest(kLocale, kLanguage, 0, std::move(cb));

  // Even if the rules are not loaded before the call to
  // StartRegionSubKeysRequest, they should get loaded in the call. Since our
  // test source is synchronous, the request will happen synchronously
  // too.
  EXPECT_TRUE(requester_->AreRulesLoadedForRegion(kLocale));
  EXPECT_EQ(subkey_receiver_->subkeys_size(), kExpectedSubkeySize);
}

}  // namespace autofill