1 // Copyright 2020 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/autofill_assistant/browser/trigger_scripts/trigger_script.h"
6
7 #include "base/test/gmock_callback_support.h"
8 #include "base/test/mock_callback.h"
9 #include "components/autofill_assistant/browser/service.pb.h"
10 #include "components/autofill_assistant/browser/trigger_scripts/dynamic_trigger_conditions.h"
11 #include "components/autofill_assistant/browser/trigger_scripts/mock_dynamic_trigger_conditions.h"
12 #include "components/autofill_assistant/browser/trigger_scripts/mock_static_trigger_conditions.h"
13 #include "components/autofill_assistant/browser/trigger_scripts/static_trigger_conditions.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15
16 namespace autofill_assistant {
17
18 using ::testing::NiceMock;
19 using ::testing::Return;
20
21 class TriggerScriptTest : public testing::Test {
22 public:
TriggerScriptTest()23 TriggerScriptTest() : trigger_script_(TriggerScriptProto()) {}
24 ~TriggerScriptTest() override = default;
25
GetProtoForTest()26 TriggerScriptProto* GetProtoForTest() { return &trigger_script_.proto_; }
27
28 protected:
29 TriggerScript trigger_script_;
30 NiceMock<MockStaticTriggerConditions> mock_static_trigger_conditions_;
31 NiceMock<MockDynamicTriggerConditions> mock_dynamic_trigger_conditions_;
32 };
33
TEST_F(TriggerScriptTest,NoTriggerConditionSucceeds)34 TEST_F(TriggerScriptTest, NoTriggerConditionSucceeds) {
35 EXPECT_TRUE(trigger_script_.EvaluateTriggerConditions(
36 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
37 }
38
TEST_F(TriggerScriptTest,EmptyTriggerConditionSucceeds)39 TEST_F(TriggerScriptTest, EmptyTriggerConditionSucceeds) {
40 GetProtoForTest()->mutable_trigger_condition();
41 EXPECT_TRUE(trigger_script_.EvaluateTriggerConditions(
42 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
43 }
44
TEST_F(TriggerScriptTest,AllOfSucceedsIfEmpty)45 TEST_F(TriggerScriptTest, AllOfSucceedsIfEmpty) {
46 GetProtoForTest()->mutable_trigger_condition()->mutable_all_of();
47 EXPECT_TRUE(trigger_script_.EvaluateTriggerConditions(
48 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
49 }
50
TEST_F(TriggerScriptTest,AllOfFailsIfOnlySomeConditionsAreTrue)51 TEST_F(TriggerScriptTest, AllOfFailsIfOnlySomeConditionsAreTrue) {
52 auto* all_of =
53 GetProtoForTest()->mutable_trigger_condition()->mutable_all_of();
54 *all_of->add_conditions()->mutable_selector() = ToSelectorProto("a");
55 *all_of->add_conditions()->mutable_selector() = ToSelectorProto("b");
56 *all_of->add_conditions()->mutable_selector() = ToSelectorProto("c");
57
58 EXPECT_CALL(mock_dynamic_trigger_conditions_,
59 GetSelectorMatches(Selector(ToSelectorProto("a"))))
60 .WillOnce(Return(true));
61 EXPECT_CALL(mock_dynamic_trigger_conditions_,
62 GetSelectorMatches(Selector(ToSelectorProto("b"))))
63 .WillOnce(Return(false));
64 // "b" already fails, "c" does not need to be evaluated.
65 EXPECT_CALL(mock_dynamic_trigger_conditions_,
66 GetSelectorMatches(Selector(ToSelectorProto("c"))))
67 .Times(0);
68
69 EXPECT_FALSE(trigger_script_.EvaluateTriggerConditions(
70 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
71 }
72
TEST_F(TriggerScriptTest,AllOfSucceedsIfAllConditionsAreTrue)73 TEST_F(TriggerScriptTest, AllOfSucceedsIfAllConditionsAreTrue) {
74 auto* all_of =
75 GetProtoForTest()->mutable_trigger_condition()->mutable_all_of();
76 *all_of->add_conditions()->mutable_selector() = ToSelectorProto("a");
77 *all_of->add_conditions()->mutable_selector() = ToSelectorProto("b");
78 *all_of->add_conditions()->mutable_selector() = ToSelectorProto("c");
79
80 EXPECT_CALL(mock_dynamic_trigger_conditions_,
81 GetSelectorMatches(Selector(ToSelectorProto("a"))))
82 .WillOnce(Return(true));
83 EXPECT_CALL(mock_dynamic_trigger_conditions_,
84 GetSelectorMatches(Selector(ToSelectorProto("b"))))
85 .WillOnce(Return(true));
86 EXPECT_CALL(mock_dynamic_trigger_conditions_,
87 GetSelectorMatches(Selector(ToSelectorProto("c"))))
88 .WillOnce(Return(true));
89
90 EXPECT_TRUE(trigger_script_.EvaluateTriggerConditions(
91 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
92 }
93
TEST_F(TriggerScriptTest,AnyOfFailsIfEmpty)94 TEST_F(TriggerScriptTest, AnyOfFailsIfEmpty) {
95 GetProtoForTest()->mutable_trigger_condition()->mutable_any_of();
96 EXPECT_FALSE(trigger_script_.EvaluateTriggerConditions(
97 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
98 }
99
TEST_F(TriggerScriptTest,AnyOfSucceedsIfSomeConditionsAreTrue)100 TEST_F(TriggerScriptTest, AnyOfSucceedsIfSomeConditionsAreTrue) {
101 auto* any_of =
102 GetProtoForTest()->mutable_trigger_condition()->mutable_any_of();
103 *any_of->add_conditions()->mutable_selector() = ToSelectorProto("a");
104 *any_of->add_conditions()->mutable_selector() = ToSelectorProto("b");
105 *any_of->add_conditions()->mutable_selector() = ToSelectorProto("c");
106
107 EXPECT_CALL(mock_dynamic_trigger_conditions_,
108 GetSelectorMatches(Selector(ToSelectorProto("a"))))
109 .WillOnce(Return(false));
110 EXPECT_CALL(mock_dynamic_trigger_conditions_,
111 GetSelectorMatches(Selector(ToSelectorProto("b"))))
112 .WillOnce(Return(true));
113 // "b" already succeeds, "c" does not need to be evaluated.
114 EXPECT_CALL(mock_dynamic_trigger_conditions_,
115 GetSelectorMatches(Selector(ToSelectorProto("c"))))
116 .Times(0);
117
118 EXPECT_TRUE(trigger_script_.EvaluateTriggerConditions(
119 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
120 }
121
TEST_F(TriggerScriptTest,AnyOfFailsIfAllConditionsAreFalse)122 TEST_F(TriggerScriptTest, AnyOfFailsIfAllConditionsAreFalse) {
123 auto* any_of =
124 GetProtoForTest()->mutable_trigger_condition()->mutable_any_of();
125 *any_of->add_conditions()->mutable_selector() = ToSelectorProto("a");
126 *any_of->add_conditions()->mutable_selector() = ToSelectorProto("b");
127 *any_of->add_conditions()->mutable_selector() = ToSelectorProto("c");
128
129 EXPECT_CALL(mock_dynamic_trigger_conditions_,
130 GetSelectorMatches(Selector(ToSelectorProto("a"))))
131 .WillOnce(Return(false));
132 EXPECT_CALL(mock_dynamic_trigger_conditions_,
133 GetSelectorMatches(Selector(ToSelectorProto("b"))))
134 .WillOnce(Return(false));
135 EXPECT_CALL(mock_dynamic_trigger_conditions_,
136 GetSelectorMatches(Selector(ToSelectorProto("c"))))
137 .WillOnce(Return(false));
138
139 EXPECT_FALSE(trigger_script_.EvaluateTriggerConditions(
140 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
141 }
142
TEST_F(TriggerScriptTest,NoneOfSucceedsIfEmpty)143 TEST_F(TriggerScriptTest, NoneOfSucceedsIfEmpty) {
144 GetProtoForTest()->mutable_trigger_condition()->mutable_none_of();
145 EXPECT_TRUE(trigger_script_.EvaluateTriggerConditions(
146 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
147 }
148
TEST_F(TriggerScriptTest,NoneOfFailsIfSomeConditionsAreTrue)149 TEST_F(TriggerScriptTest, NoneOfFailsIfSomeConditionsAreTrue) {
150 auto* none_of =
151 GetProtoForTest()->mutable_trigger_condition()->mutable_none_of();
152 *none_of->add_conditions()->mutable_selector() = ToSelectorProto("a");
153 *none_of->add_conditions()->mutable_selector() = ToSelectorProto("b");
154 *none_of->add_conditions()->mutable_selector() = ToSelectorProto("c");
155
156 EXPECT_CALL(mock_dynamic_trigger_conditions_,
157 GetSelectorMatches(Selector(ToSelectorProto("a"))))
158 .WillOnce(Return(false));
159 EXPECT_CALL(mock_dynamic_trigger_conditions_,
160 GetSelectorMatches(Selector(ToSelectorProto("b"))))
161 .WillOnce(Return(true));
162 // "b" already succeeds, "c" does not need to be evaluated.
163 EXPECT_CALL(mock_dynamic_trigger_conditions_,
164 GetSelectorMatches(Selector(ToSelectorProto("c"))))
165 .Times(0);
166
167 EXPECT_FALSE(trigger_script_.EvaluateTriggerConditions(
168 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
169 }
170
TEST_F(TriggerScriptTest,NoneOfSucceedsIfAllConditionsAreFalse)171 TEST_F(TriggerScriptTest, NoneOfSucceedsIfAllConditionsAreFalse) {
172 auto* none_of =
173 GetProtoForTest()->mutable_trigger_condition()->mutable_none_of();
174 *none_of->add_conditions()->mutable_selector() = ToSelectorProto("a");
175 *none_of->add_conditions()->mutable_selector() = ToSelectorProto("b");
176 *none_of->add_conditions()->mutable_selector() = ToSelectorProto("c");
177
178 EXPECT_CALL(mock_dynamic_trigger_conditions_,
179 GetSelectorMatches(Selector(ToSelectorProto("a"))))
180 .WillOnce(Return(false));
181 EXPECT_CALL(mock_dynamic_trigger_conditions_,
182 GetSelectorMatches(Selector(ToSelectorProto("b"))))
183 .WillOnce(Return(false));
184 EXPECT_CALL(mock_dynamic_trigger_conditions_,
185 GetSelectorMatches(Selector(ToSelectorProto("c"))))
186 .WillOnce(Return(false));
187
188 EXPECT_TRUE(trigger_script_.EvaluateTriggerConditions(
189 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
190 }
191
TEST_F(TriggerScriptTest,ComplexConditions)192 TEST_F(TriggerScriptTest, ComplexConditions) {
193 // Tests the condition a && (b || !(c)).
194 auto* all_of =
195 GetProtoForTest()->mutable_trigger_condition()->mutable_all_of();
196 *all_of->add_conditions()->mutable_selector() = ToSelectorProto("a");
197 auto* any_of = all_of->add_conditions()->mutable_any_of();
198 *any_of->add_conditions()->mutable_selector() = ToSelectorProto("b");
199 auto* none_of = any_of->add_conditions()->mutable_none_of();
200 *none_of->add_conditions()->mutable_selector() = ToSelectorProto("c");
201
202 // a == false, b == *, c == * -> false
203 EXPECT_CALL(mock_dynamic_trigger_conditions_,
204 GetSelectorMatches(Selector(ToSelectorProto("a"))))
205 .WillOnce(Return(false));
206 EXPECT_CALL(mock_dynamic_trigger_conditions_,
207 GetSelectorMatches(Selector(ToSelectorProto("b"))))
208 .Times(0);
209 EXPECT_CALL(mock_dynamic_trigger_conditions_,
210 GetSelectorMatches(Selector(ToSelectorProto("c"))))
211 .Times(0);
212 EXPECT_FALSE(trigger_script_.EvaluateTriggerConditions(
213 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
214
215 // a == true, b == true, c == * -> true
216 EXPECT_CALL(mock_dynamic_trigger_conditions_,
217 GetSelectorMatches(Selector(ToSelectorProto("a"))))
218 .WillOnce(Return(true));
219 EXPECT_CALL(mock_dynamic_trigger_conditions_,
220 GetSelectorMatches(Selector(ToSelectorProto("b"))))
221 .WillOnce(Return(true));
222 EXPECT_CALL(mock_dynamic_trigger_conditions_,
223 GetSelectorMatches(Selector(ToSelectorProto("c"))))
224 .Times(0);
225 EXPECT_TRUE(trigger_script_.EvaluateTriggerConditions(
226 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
227
228 // a == true, b == false, c == true -> false
229 EXPECT_CALL(mock_dynamic_trigger_conditions_,
230 GetSelectorMatches(Selector(ToSelectorProto("a"))))
231 .WillOnce(Return(true));
232 EXPECT_CALL(mock_dynamic_trigger_conditions_,
233 GetSelectorMatches(Selector(ToSelectorProto("b"))))
234 .WillOnce(Return(false));
235 EXPECT_CALL(mock_dynamic_trigger_conditions_,
236 GetSelectorMatches(Selector(ToSelectorProto("c"))))
237 .WillOnce(Return(true));
238 EXPECT_FALSE(trigger_script_.EvaluateTriggerConditions(
239 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
240
241 // a == true, b == false, c == false -> true
242 EXPECT_CALL(mock_dynamic_trigger_conditions_,
243 GetSelectorMatches(Selector(ToSelectorProto("a"))))
244 .WillOnce(Return(true));
245 EXPECT_CALL(mock_dynamic_trigger_conditions_,
246 GetSelectorMatches(Selector(ToSelectorProto("b"))))
247 .WillOnce(Return(false));
248 EXPECT_CALL(mock_dynamic_trigger_conditions_,
249 GetSelectorMatches(Selector(ToSelectorProto("c"))))
250 .WillOnce(Return(false));
251 EXPECT_TRUE(trigger_script_.EvaluateTriggerConditions(
252 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
253 }
254
TEST_F(TriggerScriptTest,StaticTriggerConditions)255 TEST_F(TriggerScriptTest, StaticTriggerConditions) {
256 auto* all_of =
257 GetProtoForTest()->mutable_trigger_condition()->mutable_all_of();
258 all_of->add_conditions()->mutable_stored_login_credentials();
259 all_of->add_conditions()->mutable_is_first_time_user();
260 all_of->add_conditions()->set_experiment_id(12);
261
262 EXPECT_CALL(mock_static_trigger_conditions_, is_first_time_user)
263 .WillOnce(Return(true));
264 EXPECT_CALL(mock_static_trigger_conditions_, has_stored_login_credentials)
265 .WillOnce(Return(true));
266 EXPECT_CALL(mock_static_trigger_conditions_, is_in_experiment(12))
267 .WillOnce(Return(true));
268 EXPECT_TRUE(trigger_script_.EvaluateTriggerConditions(
269 mock_static_trigger_conditions_, mock_dynamic_trigger_conditions_));
270 }
271
272 } // namespace autofill_assistant
273