1 // Copyright 2015 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.
5 #include "base/strings/string_number_conversions.h"
6 #include "content/browser/notifications/notification_id_generator.h"
7 #include "content/public/test/test_browser_context.h"
8 #include "testing/gtest/include/gtest/gtest.h"
14 const int kRenderProcessId
= 42;
15 const int64_t kPersistentNotificationId
= 430;
16 const int kNonPersistentNotificationId
= 5400;
17 const char kExampleTag
[] = "example";
19 class TestBrowserContextConfigurableIncognito
: public TestBrowserContext
{
21 TestBrowserContextConfigurableIncognito() {}
22 ~TestBrowserContextConfigurableIncognito() override
{}
24 void set_incognito(bool incognito
) { incognito_
= incognito
; }
26 // TestBrowserContext implementation.
27 bool IsOffTheRecord() const override
{ return incognito_
; }
30 bool incognito_
= false;
32 DISALLOW_COPY_AND_ASSIGN(TestBrowserContextConfigurableIncognito
);
35 class NotificationIdGeneratorTest
: public ::testing::Test
{
37 NotificationIdGeneratorTest()
38 : generator_(&browser_context_
, kRenderProcessId
) {}
40 void SetUp() override
{
45 GURL
origin() const { return GURL("https://example.com"); }
47 TestBrowserContextConfigurableIncognito
* browser_context() {
48 return &browser_context_
;
51 NotificationIdGenerator
* generator() { return &generator_
; }
54 TestBrowserContextConfigurableIncognito browser_context_
;
55 NotificationIdGenerator generator_
;
58 // -----------------------------------------------------------------------------
59 // Persistent and non-persistent notifications
61 // Tests that cover logic common to both persistent and non-persistent
62 // notifications: different browser contexts, Incognito mode or not,
64 // Two calls to the generator with exactly the same information should result
65 // in exactly the same notification ids being generated.
66 TEST_F(NotificationIdGeneratorTest
, DeterministicGeneration
) {
67 // Persistent notifications.
69 generator()->GenerateForPersistentNotification(
70 origin(), kExampleTag
, kPersistentNotificationId
),
71 generator()->GenerateForPersistentNotification(
72 origin(), kExampleTag
, kPersistentNotificationId
));
75 generator()->GenerateForPersistentNotification(
76 origin(), "" /* tag */, kPersistentNotificationId
),
77 generator()->GenerateForPersistentNotification(
78 origin(), "" /* tag */, kPersistentNotificationId
));
80 // Non-persistent notifications.
82 generator()->GenerateForNonPersistentNotification(
83 origin(), kExampleTag
, kNonPersistentNotificationId
),
84 generator()->GenerateForNonPersistentNotification(
85 origin(), kExampleTag
, kNonPersistentNotificationId
));
88 generator()->GenerateForNonPersistentNotification(
89 origin(), "" /* tag */, kNonPersistentNotificationId
),
90 generator()->GenerateForNonPersistentNotification(
91 origin(), "" /* tag */, kNonPersistentNotificationId
));
94 // Uniqueness of notification ids will be impacted by the browser context.
95 TEST_F(NotificationIdGeneratorTest
, DifferentBrowserContexts
) {
96 TestBrowserContextConfigurableIncognito second_browser_context
;
97 NotificationIdGenerator
second_generator(&second_browser_context
,
100 // Persistent notifications.
102 generator()->GenerateForPersistentNotification(
103 origin(), kExampleTag
, kPersistentNotificationId
),
104 second_generator
.GenerateForPersistentNotification(
105 origin(), kExampleTag
, kPersistentNotificationId
));
108 generator()->GenerateForPersistentNotification(
109 origin(), "" /* tag */, kPersistentNotificationId
),
110 second_generator
.GenerateForPersistentNotification(
111 origin(), "" /* tag */, kPersistentNotificationId
));
113 // Non-persistent notifications.
115 generator()->GenerateForNonPersistentNotification(
116 origin(), kExampleTag
, kNonPersistentNotificationId
),
117 second_generator
.GenerateForNonPersistentNotification(
118 origin(), kExampleTag
, kNonPersistentNotificationId
));
121 generator()->GenerateForNonPersistentNotification(
122 origin(), "" /* tag */, kNonPersistentNotificationId
),
123 second_generator
.GenerateForNonPersistentNotification(
124 origin(), "" /* tag */, kNonPersistentNotificationId
));
127 // Uniqueness of notification ids will be impacted by the fact whether the
128 // browser context is in Incognito mode.
129 TEST_F(NotificationIdGeneratorTest
, DifferentIncognitoStates
) {
130 ASSERT_FALSE(browser_context()->IsOffTheRecord());
132 // Persistent notifications.
133 std::string normal_persistent_notification_id
=
134 generator()->GenerateForPersistentNotification(
135 origin(), kExampleTag
, kPersistentNotificationId
);
137 browser_context()->set_incognito(true);
138 ASSERT_TRUE(browser_context()->IsOffTheRecord());
140 std::string incognito_persistent_notification_id
=
141 generator()->GenerateForPersistentNotification(
142 origin(), kExampleTag
, kPersistentNotificationId
);
144 EXPECT_NE(normal_persistent_notification_id
,
145 incognito_persistent_notification_id
);
147 browser_context()->set_incognito(false);
149 // Non-persistent notifications.
150 ASSERT_FALSE(browser_context()->IsOffTheRecord());
152 std::string normal_non_persistent_notification_id
=
153 generator()->GenerateForNonPersistentNotification(
154 origin(), kExampleTag
, kNonPersistentNotificationId
);
156 browser_context()->set_incognito(true);
157 ASSERT_TRUE(browser_context()->IsOffTheRecord());
159 std::string incognito_non_persistent_notification_id
=
160 generator()->GenerateForNonPersistentNotification(
161 origin(), kExampleTag
, kNonPersistentNotificationId
);
163 EXPECT_NE(normal_non_persistent_notification_id
,
164 incognito_non_persistent_notification_id
);
167 // The origin of the notification will impact the generated notification id.
168 TEST_F(NotificationIdGeneratorTest
, DifferentOrigins
) {
169 GURL
different_origin("https://example2.com");
171 // Persistent notifications.
173 generator()->GenerateForPersistentNotification(
174 origin(), kExampleTag
, kPersistentNotificationId
),
175 generator()->GenerateForPersistentNotification(
176 different_origin
, kExampleTag
, kPersistentNotificationId
));
178 // Non-persistent notifications.
180 generator()->GenerateForNonPersistentNotification(
181 origin(), kExampleTag
, kNonPersistentNotificationId
),
182 generator()->GenerateForNonPersistentNotification(
183 different_origin
, kExampleTag
, kNonPersistentNotificationId
));
186 // The tag, when non-empty, will impact the generated notification id.
187 TEST_F(NotificationIdGeneratorTest
, DifferentTags
) {
188 const std::string
& different_tag
= std::string(kExampleTag
) + "2";
190 // Persistent notifications.
192 generator()->GenerateForPersistentNotification(
193 origin(), kExampleTag
, kPersistentNotificationId
),
194 generator()->GenerateForPersistentNotification(
195 origin(), different_tag
, kPersistentNotificationId
));
197 // Non-persistent notifications.
199 generator()->GenerateForNonPersistentNotification(
200 origin(), kExampleTag
, kNonPersistentNotificationId
),
201 generator()->GenerateForNonPersistentNotification(
202 origin(), different_tag
, kNonPersistentNotificationId
));
205 // The persistent or non-persistent notification id will impact the generated
206 // notification id when the tag is empty.
207 TEST_F(NotificationIdGeneratorTest
, DifferentIds
) {
208 NotificationIdGenerator
second_generator(browser_context(),
209 kRenderProcessId
+ 1);
211 // Persistent notifications.
213 generator()->GenerateForPersistentNotification(
214 origin(), "" /* tag */, kPersistentNotificationId
),
215 generator()->GenerateForPersistentNotification(
216 origin(), "" /* tag */, kPersistentNotificationId
+ 1));
218 // Non-persistent notifications.
220 generator()->GenerateForNonPersistentNotification(
221 origin(), "" /* tag */, kNonPersistentNotificationId
),
222 generator()->GenerateForNonPersistentNotification(
223 origin(), "" /* tag */, kNonPersistentNotificationId
+ 1));
225 // Non-persistent when a tag is being used.
227 generator()->GenerateForNonPersistentNotification(
228 origin(), kExampleTag
, kNonPersistentNotificationId
),
229 second_generator
.GenerateForNonPersistentNotification(
230 origin(), kExampleTag
, kNonPersistentNotificationId
));
233 // Using a numeric tag that could resemble a persistent notification id should
234 // not be equal to a notification without a tag, but with that id.
235 TEST_F(NotificationIdGeneratorTest
, NumericTagAmbiguity
) {
236 // Persistent notifications.
238 generator()->GenerateForPersistentNotification(
240 base::IntToString(kPersistentNotificationId
),
241 kPersistentNotificationId
),
242 generator()->GenerateForPersistentNotification(
243 origin(), "" /* tag */, kPersistentNotificationId
));
245 // Non-persistent notifications.
247 generator()->GenerateForNonPersistentNotification(
249 base::IntToString(kNonPersistentNotificationId
),
250 kNonPersistentNotificationId
),
251 generator()->GenerateForNonPersistentNotification(
252 origin(), "" /* tag */, kNonPersistentNotificationId
));
255 // Using port numbers and a tag which, when concatenated, could end up being
256 // equal to each other if origins stop ending with slashes.
257 TEST_F(NotificationIdGeneratorTest
, OriginPortAmbiguity
) {
258 GURL
origin_805("https://example.com:805");
259 GURL
origin_8051("https://example.com:8051");
261 // Persistent notifications.
263 generator()->GenerateForPersistentNotification(
264 origin_805
, "17", kPersistentNotificationId
),
265 generator()->GenerateForPersistentNotification(
266 origin_8051
, "7", kPersistentNotificationId
));
268 // Non-persistent notifications.
270 generator()->GenerateForNonPersistentNotification(
271 origin_805
, "17", kNonPersistentNotificationId
),
272 generator()->GenerateForNonPersistentNotification(
273 origin_8051
, "7", kNonPersistentNotificationId
));
276 // -----------------------------------------------------------------------------
277 // Persistent notifications
279 // Tests covering the logic specific to persistent notifications. This kind of
280 // notification does not care about the renderer process that created them.
282 TEST_F(NotificationIdGeneratorTest
, PersistentDifferentRenderProcessIds
) {
283 NotificationIdGenerator
second_generator(browser_context(),
284 kRenderProcessId
+ 1);
287 generator()->GenerateForPersistentNotification(
288 origin(), kExampleTag
, kPersistentNotificationId
),
289 second_generator
.GenerateForPersistentNotification(
290 origin(), kExampleTag
, kPersistentNotificationId
));
293 generator()->GenerateForPersistentNotification(
294 origin(), "" /* tag */, kPersistentNotificationId
),
295 second_generator
.GenerateForPersistentNotification(
296 origin(), "" /* tag */, kPersistentNotificationId
));
299 // -----------------------------------------------------------------------------
300 // Non-persistent notifications
302 // Tests covering the logic specific to non-persistent notifications. This kind
303 // of notification cares about the renderer process they were created by when
304 // the notification does not have a tag, since multiple renderers would restart
305 // the count for non-persistent notification ids.
307 TEST_F(NotificationIdGeneratorTest
, NonPersistentDifferentRenderProcessIds
) {
308 NotificationIdGenerator
second_generator(browser_context(),
309 kRenderProcessId
+ 1);
312 generator()->GenerateForNonPersistentNotification(
313 origin(), kExampleTag
, kNonPersistentNotificationId
),
314 second_generator
.GenerateForNonPersistentNotification(
315 origin(), kExampleTag
, kNonPersistentNotificationId
));
318 generator()->GenerateForNonPersistentNotification(
319 origin(), "" /* tag */, kNonPersistentNotificationId
),
320 second_generator
.GenerateForNonPersistentNotification(
321 origin(), "" /* tag */, kNonPersistentNotificationId
));
324 // Concatenation of the render process id and the non-persistent notification
325 // id should not result in the generation of a duplicated notification id.
326 TEST_F(NotificationIdGeneratorTest
, NonPersistentRenderProcessIdAmbiguity
) {
327 NotificationIdGenerator
generator_rpi_5(browser_context(), 5);
328 NotificationIdGenerator
generator_rpi_51(browser_context(), 51);
331 generator_rpi_5
.GenerateForNonPersistentNotification(
332 origin(), "" /* tag */, 1337 /* non_persistent_notification_id */),
333 generator_rpi_51
.GenerateForNonPersistentNotification(
334 origin(), "" /* tag */, 337 /* non_persistent_notification_id */));
338 } // namespace content