1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/omnibox/browser/omnibox_pedal.h"
6 
7 #include "base/strings/utf_string_conversions.h"
8 #include "components/omnibox/browser/omnibox_pedal_implementations.h"
9 #include "components/omnibox/browser/omnibox_pedal_provider.h"
10 #include "components/strings/grit/components_strings.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "url/gurl.h"
13 
14 class OmniboxPedalTest : public testing::Test {
15  protected:
OmniboxPedalTest()16   OmniboxPedalTest() {}
17 };
18 
TEST_F(OmniboxPedalTest,SynonymGroupRespectsSingle)19 TEST_F(OmniboxPedalTest, SynonymGroupRespectsSingle) {
20   {
21     // Test |match_once| = true:
22     // Only one instance of first found representative should be removed.
23     auto group = OmniboxPedal::SynonymGroup(true, true, 2);
24     group.AddSynonym({1, 2});
25     group.AddSynonym({3});
26     OmniboxPedal::Tokens sequence = {1, 2, 3, 1, 2};
27     EXPECT_EQ(sequence.size(), size_t{5});
28     const bool found = group.EraseMatchesIn(&sequence);
29     EXPECT_TRUE(found);
30     EXPECT_EQ(sequence.size(), size_t{3});
31   }
32   {
33     // Test |match_once| = false:
34     // All matches should be removed.
35     auto group = OmniboxPedal::SynonymGroup(true, false, 2);
36     group.AddSynonym({1, 2});
37     group.AddSynonym({3});
38     OmniboxPedal::Tokens sequence = {1, 2, 3, 5, 1, 2};
39     EXPECT_EQ(sequence.size(), size_t{6});
40     const bool found = group.EraseMatchesIn(&sequence);
41     EXPECT_TRUE(found);
42     EXPECT_EQ(sequence.size(), size_t{1});
43   }
44 }
45 
TEST_F(OmniboxPedalTest,SynonymGroupsDriveConceptMatches)46 TEST_F(OmniboxPedalTest, SynonymGroupsDriveConceptMatches) {
47   constexpr int optional = 1;
48   constexpr int required_a = 2;
49   constexpr int required_b = 3;
50   constexpr int nonsense = 4;
51   OmniboxPedal test_pedal(
52       OmniboxPedalId::CLEAR_BROWSING_DATA,
53       OmniboxPedal::LabelStrings(
54           IDS_OMNIBOX_PEDAL_CLEAR_BROWSING_DATA_HINT,
55           IDS_OMNIBOX_PEDAL_CLEAR_BROWSING_DATA_HINT_SHORT,
56           IDS_OMNIBOX_PEDAL_CLEAR_BROWSING_DATA_SUGGESTION_CONTENTS,
57           IDS_ACC_OMNIBOX_PEDAL_CLEAR_BROWSING_DATA_SUFFIX,
58           IDS_ACC_OMNIBOX_PEDAL_CLEAR_BROWSING_DATA),
59       GURL());
60   const auto add_group = [&](bool required, int token) {
61     OmniboxPedal::SynonymGroup group(required, true, 1);
62     group.AddSynonym({token});
63     test_pedal.AddSynonymGroup(std::move(group));
64   };
65   add_group(false, optional);
66   add_group(true, required_a);
67   add_group(true, required_b);
68 
69   const auto is_concept_match = [&](const OmniboxPedal::Tokens& sequence) {
70     return test_pedal.IsConceptMatch(sequence);
71   };
72 
73   // As long as required synonym groups are present, order shouldn't matter.
74   EXPECT_TRUE(is_concept_match({required_a, required_b}));
75   EXPECT_TRUE(is_concept_match({required_b, required_a}));
76 
77   // Optional groups may be added without stopping trigger.
78   EXPECT_TRUE(is_concept_match({required_a, required_b, optional}));
79   EXPECT_TRUE(is_concept_match({required_a, optional, required_b}));
80   EXPECT_TRUE(is_concept_match({optional, required_b, required_a}));
81 
82   // Any required group's absence will stop trigger.
83   EXPECT_FALSE(is_concept_match({required_a, optional}));
84   EXPECT_FALSE(is_concept_match({nonsense}));
85   EXPECT_FALSE(is_concept_match({nonsense, optional}));
86 
87   // Presence of extra text will stop trigger even with all required present.
88   EXPECT_FALSE(is_concept_match({required_a, required_b, nonsense, optional}));
89   EXPECT_FALSE(is_concept_match({required_b, required_a, nonsense}));
90 
91   // This includes extra instances of optional groups, since it is match_once.
92   EXPECT_FALSE(is_concept_match({required_b, required_a, optional, optional}));
93 }
94