blob: 9991850802718a29204f9449e40470d6922849f9 [file] [log] [blame]
// Copyright 2015 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 <stdint.h>
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/notifications/notification_id_generator.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace content {
namespace {
const int kRenderProcessId = 42;
const int64_t kPersistentNotificationId = 430;
const int kNonPersistentNotificationId = 5400;
const char kExampleTag[] = "example";
class NotificationIdGeneratorTest : public ::testing::Test {
public:
NotificationIdGeneratorTest() : origin_("https://example.com") {}
protected:
GURL origin_;
NotificationIdGenerator generator_;
};
// -----------------------------------------------------------------------------
// Persistent and non-persistent notifications
// Two calls to the generator with exactly the same information should result
// in exactly the same notification ids being generated.
TEST_F(NotificationIdGeneratorTest, DeterministicGeneration) {
// Persistent notifications.
EXPECT_EQ(generator_.GenerateForPersistentNotification(
origin_, kExampleTag, kPersistentNotificationId),
generator_.GenerateForPersistentNotification(
origin_, kExampleTag, kPersistentNotificationId));
EXPECT_EQ(generator_.GenerateForPersistentNotification(
origin_, "" /* tag */, kPersistentNotificationId),
generator_.GenerateForPersistentNotification(
origin_, "" /* tag */, kPersistentNotificationId));
// Non-persistent notifications.
EXPECT_EQ(
generator_.GenerateForNonPersistentNotification(
origin_, kExampleTag, kNonPersistentNotificationId, kRenderProcessId),
generator_.GenerateForNonPersistentNotification(
origin_, kExampleTag, kNonPersistentNotificationId,
kRenderProcessId));
EXPECT_EQ(generator_.GenerateForNonPersistentNotification(
origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId),
generator_.GenerateForNonPersistentNotification(
origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId));
}
// The origin of the notification will impact the generated notification id.
TEST_F(NotificationIdGeneratorTest, DifferentOrigins) {
GURL different_origin("https://example2.com");
// Persistent notifications.
EXPECT_NE(generator_.GenerateForPersistentNotification(
origin_, kExampleTag, kPersistentNotificationId),
generator_.GenerateForPersistentNotification(
different_origin, kExampleTag, kPersistentNotificationId));
// Non-persistent notifications.
EXPECT_NE(
generator_.GenerateForNonPersistentNotification(
origin_, kExampleTag, kNonPersistentNotificationId, kRenderProcessId),
generator_.GenerateForNonPersistentNotification(
different_origin, kExampleTag, kNonPersistentNotificationId,
kRenderProcessId));
}
// The tag, when non-empty, will impact the generated notification id.
TEST_F(NotificationIdGeneratorTest, DifferentTags) {
const std::string& different_tag = std::string(kExampleTag) + "2";
// Persistent notifications.
EXPECT_NE(generator_.GenerateForPersistentNotification(
origin_, kExampleTag, kPersistentNotificationId),
generator_.GenerateForPersistentNotification(
origin_, different_tag, kPersistentNotificationId));
// Non-persistent notifications.
EXPECT_NE(
generator_.GenerateForNonPersistentNotification(
origin_, kExampleTag, kNonPersistentNotificationId, kRenderProcessId),
generator_.GenerateForNonPersistentNotification(
origin_, different_tag, kNonPersistentNotificationId,
kRenderProcessId));
}
// The persistent or non-persistent notification id will impact the generated
// notification id when the tag is empty.
TEST_F(NotificationIdGeneratorTest, DifferentIds) {
// Persistent notifications.
EXPECT_NE(generator_.GenerateForPersistentNotification(
origin_, "" /* tag */, kPersistentNotificationId),
generator_.GenerateForPersistentNotification(
origin_, "" /* tag */, kPersistentNotificationId + 1));
// Non-persistent notifications.
EXPECT_NE(generator_.GenerateForNonPersistentNotification(
origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId),
generator_.GenerateForNonPersistentNotification(
origin_, "" /* tag */, kNonPersistentNotificationId + 1,
kRenderProcessId));
// Non-persistent when a tag is being used.
EXPECT_EQ(
generator_.GenerateForNonPersistentNotification(
origin_, kExampleTag, kNonPersistentNotificationId, kRenderProcessId),
generator_.GenerateForNonPersistentNotification(
origin_, kExampleTag, kNonPersistentNotificationId,
kRenderProcessId + 1));
}
// Using a numeric tag that could resemble a persistent notification id should
// not be equal to a notification without a tag, but with that id.
TEST_F(NotificationIdGeneratorTest, NumericTagAmbiguity) {
// Persistent notifications.
EXPECT_NE(generator_.GenerateForPersistentNotification(
origin_, base::Int64ToString(kPersistentNotificationId),
kPersistentNotificationId),
generator_.GenerateForPersistentNotification(
origin_, "" /* tag */, kPersistentNotificationId));
// Non-persistent notifications.
EXPECT_NE(generator_.GenerateForNonPersistentNotification(
origin_, base::IntToString(kNonPersistentNotificationId),
kNonPersistentNotificationId, kRenderProcessId),
generator_.GenerateForNonPersistentNotification(
origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId));
}
// Using port numbers and a tag which, when concatenated, could end up being
// equal to each other if origins stop ending with slashes.
TEST_F(NotificationIdGeneratorTest, OriginPortAmbiguity) {
GURL origin_805("https://example.com:805");
GURL origin_8051("https://example.com:8051");
// Persistent notifications.
EXPECT_NE(generator_.GenerateForPersistentNotification(
origin_805, "17", kPersistentNotificationId),
generator_.GenerateForPersistentNotification(
origin_8051, "7", kPersistentNotificationId));
// Non-persistent notifications.
EXPECT_NE(
generator_.GenerateForNonPersistentNotification(
origin_805, "17", kNonPersistentNotificationId, kRenderProcessId),
generator_.GenerateForNonPersistentNotification(
origin_8051, "7", kNonPersistentNotificationId, kRenderProcessId));
}
// Verifies that the static Is(Non)PersistentNotification helpers can correctly
// identify persistent and non-persistent notification IDs.
TEST_F(NotificationIdGeneratorTest, DetectIdFormat) {
std::string persistent_id = generator_.GenerateForPersistentNotification(
origin_, "" /* tag */, kPersistentNotificationId);
std::string non_persistent_id =
generator_.GenerateForNonPersistentNotification(
origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId);
EXPECT_TRUE(NotificationIdGenerator::IsPersistentNotification(persistent_id));
EXPECT_FALSE(
NotificationIdGenerator::IsNonPersistentNotification(persistent_id));
EXPECT_TRUE(
NotificationIdGenerator::IsNonPersistentNotification(non_persistent_id));
EXPECT_FALSE(
NotificationIdGenerator::IsPersistentNotification(non_persistent_id));
}
// -----------------------------------------------------------------------------
// Persistent notifications
//
// Tests covering the logic specific to persistent notifications. This kind of
// notification does not care about the renderer process that created them.
TEST_F(NotificationIdGeneratorTest, PersistentDifferentRenderProcessIds) {
NotificationIdGenerator second_generator;
EXPECT_EQ(generator_.GenerateForPersistentNotification(
origin_, kExampleTag, kPersistentNotificationId),
second_generator.GenerateForPersistentNotification(
origin_, kExampleTag, kPersistentNotificationId));
EXPECT_EQ(generator_.GenerateForPersistentNotification(
origin_, "" /* tag */, kPersistentNotificationId),
second_generator.GenerateForPersistentNotification(
origin_, "" /* tag */, kPersistentNotificationId));
}
// -----------------------------------------------------------------------------
// Non-persistent notifications
//
// Tests covering the logic specific to non-persistent notifications. This kind
// of notification cares about the renderer process they were created by when
// the notification does not have a tag, since multiple renderers would restart
// the count for non-persistent notification ids.
TEST_F(NotificationIdGeneratorTest, NonPersistentDifferentRenderProcessIds) {
EXPECT_EQ(
generator_.GenerateForNonPersistentNotification(
origin_, kExampleTag, kNonPersistentNotificationId, kRenderProcessId),
generator_.GenerateForNonPersistentNotification(
origin_, kExampleTag, kNonPersistentNotificationId,
kRenderProcessId + 1));
EXPECT_NE(generator_.GenerateForNonPersistentNotification(
origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId),
generator_.GenerateForNonPersistentNotification(
origin_, "" /* tag */, kNonPersistentNotificationId,
kRenderProcessId + 1));
}
// Concatenation of the render process id and the non-persistent notification
// id should not result in the generation of a duplicated notification id.
TEST_F(NotificationIdGeneratorTest, NonPersistentRenderProcessIdAmbiguity) {
EXPECT_NE(
generator_.GenerateForNonPersistentNotification(
origin_, "" /* tag */, 1337 /* non_persistent_notification_id */,
5 /* render_process_id */),
generator_.GenerateForNonPersistentNotification(
origin_, "" /* tag */, 337 /* non_persistent_notification_id */,
51 /* render_process_id */));
}
} // namespace
} // namespace content