Commit c5f263f5 authored by Mohamed Adel's avatar Mohamed Adel Committed by Commit Bot

Add user defined categories to UNNotifications

-Adds complex categories that support 2 developer buttons

-Moves all init methods from builders to the base builder

-Modifies response builder to accommodate for developer buttons

-Tests the built category and its response

Bug: 1136061
Change-Id: Ifabb0d06e8379f957ff8af7ab4bc8ea2228cf38d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2471637
Commit-Queue: Mohamed Adel <adelm@google.com>
Reviewed-by: default avatarRichard Knoll <knollr@chromium.org>
Reviewed-by: default avatarRayan Kanso <rayankans@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817457}
parent 1444cfe0
......@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_PLATFORM_BRIDGE_MAC_UNNOTIFICATION_H_
#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_PLATFORM_BRIDGE_MAC_UNNOTIFICATION_H_
#import <Foundation/Foundation.h>
#include <memory>
#include <string>
......@@ -51,8 +53,6 @@ class API_AVAILABLE(macosx(10.14)) NotificationPlatformBridgeMacUNNotification
// Request permission to send notifications
void RequestPermission();
// Create default categories for banners and alerts
void CreateDefaultCategories();
private:
// Cocoa class that receives callbacks from the UNUserNotificationCenter.
......@@ -64,6 +64,9 @@ class API_AVAILABLE(macosx(10.14)) NotificationPlatformBridgeMacUNNotification
// An object that keeps temp files alive long enough for macOS to pick up.
NotificationImageRetainer image_retainer_;
// An object that carries the categories for the notifications
base::scoped_nsobject<NSMutableSet> categories_;
};
#endif // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_PLATFORM_BRIDGE_MAC_UNNOTIFICATION_H_
......@@ -19,19 +19,13 @@
#import "chrome/browser/ui/cocoa/notifications/unnotification_response_builder_mac.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/browser_task_traits.h"
#include "third_party/blink/public/common/notifications/notification_constants.h"
#include "ui/base/l10n/l10n_util_mac.h"
#include "ui/message_center/public/cpp/notification.h"
@class UNMutableNotificationContent;
@class UNUserNotificationCenter;
namespace {
NSString* const kCloseAndSettingsCategory = @"CLOSE_AND_SETTINGS";
NSString* const kCloseCategory = @"CLOSE";
} // namespace
// A Cocoa class that represents the delegate of UNUserNotificationCenter and
// can forward commands to C++.
API_AVAILABLE(macosx(10.14))
......@@ -49,12 +43,12 @@ NotificationPlatformBridgeMacUNNotification::
NotificationPlatformBridgeMacUNNotification(
UNUserNotificationCenter* notification_center)
: delegate_([UNNotificationCenterDelegate alloc]),
notification_center_([notification_center retain]) {
notification_center_([notification_center retain]),
categories_([[NSMutableSet alloc] init]) {
[notification_center_ setDelegate:delegate_.get()];
// TODO(crbug/1129366): Determine when to request permission
NotificationPlatformBridgeMacUNNotification::RequestPermission();
NotificationPlatformBridgeMacUNNotification::CreateDefaultCategories();
}
NotificationPlatformBridgeMacUNNotification::
......@@ -68,8 +62,12 @@ void NotificationPlatformBridgeMacUNNotification::Display(
Profile* profile,
const message_center::Notification& notification,
std::unique_ptr<NotificationCommon::Metadata> metadata) {
base::scoped_nsobject<UNNotificationBuilder> builder(
[[UNNotificationBuilder alloc] init]);
base::scoped_nsobject<UNNotificationBuilder> builder([[UNNotificationBuilder
alloc]
initWithCloseLabel:l10n_util::GetNSString(IDS_NOTIFICATION_BUTTON_CLOSE)
optionsLabel:l10n_util::GetNSString(IDS_NOTIFICATION_BUTTON_MORE)
settingsLabel:l10n_util::GetNSString(
IDS_NOTIFICATION_BUTTON_SETTINGS)]);
base::string16 context_message =
notification.items().empty()
......@@ -97,6 +95,18 @@ void NotificationPlatformBridgeMacUNNotification::Display(
[builder setIconPath:base::SysUTF8ToNSString(path.value())];
}
[builder setShowSettingsButton:notification.should_show_settings_button()];
const std::vector<message_center::ButtonInfo>& buttons =
notification.buttons();
if (!buttons.empty()) {
DCHECK_LE(buttons.size(), blink::kNotificationMaxActions);
NSString* buttonOne = base::SysUTF16ToNSString(buttons[0].title);
NSString* buttonTwo = nullptr;
if (buttons.size() > 1)
buttonTwo = base::SysUTF16ToNSString(buttons[1].title);
[builder setButtons:buttonOne secondaryButton:buttonTwo];
}
[builder setOrigin:base::SysUTF8ToNSString(notification.origin_url().spec())];
[builder setNotificationId:base::SysUTF8ToNSString(notification.id())];
[builder setProfileId:base::SysUTF8ToNSString(GetProfileId(profile))];
......@@ -108,14 +118,13 @@ void NotificationPlatformBridgeMacUNNotification::Display(
setNotificationType:[NSNumber numberWithInteger:static_cast<NSInteger>(
notification_type)]];
UNMutableNotificationContent* content = [builder buildUserNotification];
UNNotificationCategory* category = [builder buildCategory];
[categories_ addObject:category];
// TODO(crbug/1138470): Determine when to remove UNNotificationCategory so
// that they do not accumulate during browser lifetime
[notification_center_ setNotificationCategories:categories_];
// TODO(crbug/1136061): Add support for complex categories and move setting
// the categories to the place that will be building the complex categories
if (notification.should_show_settings_button())
[content setCategoryIdentifier:kCloseAndSettingsCategory];
else
[content setCategoryIdentifier:kCloseCategory];
UNMutableNotificationContent* content = [builder buildUserNotification];
UNNotificationRequest* request = [UNNotificationRequest
requestWithIdentifier:base::SysUTF8ToNSString(notification.id())
......@@ -217,38 +226,6 @@ void NotificationPlatformBridgeMacUNNotification::RequestPermission() {
}];
}
void NotificationPlatformBridgeMacUNNotification::CreateDefaultCategories() {
UNNotificationAction* closeButton = [UNNotificationAction
actionWithIdentifier:notification_constants::kNotificationCloseButtonTag
title:l10n_util::GetNSString(IDS_NOTIFICATION_BUTTON_CLOSE)
options:UNNotificationActionOptionNone];
UNNotificationAction* settingsButton = [UNNotificationAction
actionWithIdentifier:notification_constants::
kNotificationSettingsButtonTag
title:l10n_util::GetNSString(
IDS_NOTIFICATION_BUTTON_SETTINGS)
options:UNNotificationActionOptionForeground];
// The actions in categories are ordered by LIFO. So having closeButton at the
// end ensures that it is always the button on top.
UNNotificationCategory* closeAndSettingsCategory = [UNNotificationCategory
categoryWithIdentifier:kCloseAndSettingsCategory
actions:@[ settingsButton, closeButton ]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
UNNotificationCategory* closeCategory = [UNNotificationCategory
categoryWithIdentifier:kCloseCategory
actions:@[ closeButton ]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
[notification_center_
setNotificationCategories:[NSSet setWithObjects:closeAndSettingsCategory,
closeCategory, nil]];
}
// /////////////////////////////////////////////////////////////////////////////
@implementation UNNotificationCenterDelegate
......
......@@ -14,8 +14,10 @@
base::scoped_nsobject<NSMutableDictionary> _notificationData;
}
// Initializes an empty builder along with |_notificationData|.
- (instancetype)init;
// Initializes a builder with default values for the button labels.
- (instancetype)initWithCloseLabel:(NSString*)closeLabel
optionsLabel:(NSString*)optionsLabel
settingsLabel:(NSString*)settingsLabel;
// Initializes a builder by deserializing |data|. The |data| must have been
// generated by calling the buildDictionary function on another builder
......
......@@ -8,9 +8,20 @@
@implementation NotificationBuilderBase
- (instancetype)init {
- (instancetype)initWithCloseLabel:(NSString*)closeLabel
optionsLabel:(NSString*)optionsLabel
settingsLabel:(NSString*)settingsLabel {
if ((self = [super init])) {
_notificationData.reset([[NSMutableDictionary alloc] init]);
[_notificationData
setObject:closeLabel
forKey:notification_constants::kNotificationCloseButtonTag];
[_notificationData
setObject:optionsLabel
forKey:notification_constants::kNotificationOptionsButtonTag];
[_notificationData
setObject:settingsLabel
forKey:notification_constants::kNotificationSettingsButtonTag];
}
return self;
}
......
......@@ -19,7 +19,7 @@
// base::scoped_nsobject<NotificationBuilder> builder(
// [[NotificationBuilder alloc] initWithCloseLabel:@"Close"
// optionsLabel:@"Options"
// settingsLabel:@"Settings")]);
// settingsLabel:@"Settings"]);
// [builder setTitle:@"Hello"];
//
// // Build a notification out of the data.
......@@ -34,11 +34,6 @@
// [[NotificationBuilder alloc] initWithData:notificationData]);
@interface NotificationBuilder : NotificationBuilderBase
// Initializes a builder with default values for the button labels.
- (instancetype)initWithCloseLabel:(NSString*)closeLabel
optionsLabel:(NSString*)optionsLabel
settingsLabel:(NSString*)settingsLabel;
// Sets the icon that is displayed in the notification if present
- (void)setIcon:(NSImage*)icon;
......
......@@ -13,23 +13,6 @@
@implementation NotificationBuilder
- (instancetype)initWithCloseLabel:(NSString*)closeLabel
optionsLabel:(NSString*)optionsLabel
settingsLabel:(NSString*)settingsLabel {
if ((self = [super init])) {
[_notificationData
setObject:closeLabel
forKey:notification_constants::kNotificationCloseButtonTag];
[_notificationData
setObject:optionsLabel
forKey:notification_constants::kNotificationOptionsButtonTag];
[_notificationData
setObject:settingsLabel
forKey:notification_constants::kNotificationSettingsButtonTag];
}
return self;
}
- (void)setIcon:(NSImage*)icon {
if (!icon)
return;
......
......@@ -20,6 +20,7 @@ extern NSString* const kNotificationTag;
extern NSString* const kNotificationCloseButtonTag;
extern NSString* const kNotificationOptionsButtonTag;
extern NSString* const kNotificationSettingsButtonTag;
extern NSString* const kNotificationCategoryIdentifier;
extern NSString* const kNotificationOrigin;
extern NSString* const kNotificationId;
......
......@@ -19,6 +19,7 @@ NSString* const kNotificationTag = @"tag";
NSString* const kNotificationCloseButtonTag = @"closeButton";
NSString* const kNotificationOptionsButtonTag = @"optionsButton";
NSString* const kNotificationSettingsButtonTag = @"settingsButton";
NSString* const kNotificationCategoryIdentifier = @"categoryIdentifier";
// Applicable to NotificationBuilder and NotificationResponseBuilder
NSString* const kNotificationOrigin = @"notificationOrigin";
......
......@@ -11,13 +11,16 @@
#import "chrome/browser/ui/cocoa/notifications/notification_builder_base.h"
@class UNMutableNotificationContent;
@class UNNotificationCategory;
// Provides a marshallable way for storing the information required to construct
// a UNMutableNotificationContent that is to be displayed on the system.
//
// A quick example:
// base::scoped_nsobject<UNNotificationBuilder> builder(
// [[UNNotificationBuilder alloc] init]);
// [[UNNotificationBuilder alloc] initWithCloseLabel:@"Close"
// optionsLabel:@"Options"
// settingsLabel:@"Settings"]);
// [builder setTitle:@"Hello"];
//
// // Build a notification out of the data.
......@@ -36,6 +39,10 @@ API_AVAILABLE(macosx(10.14))
// Sets the icon path that is used to display it in the notification if present
- (void)setIconPath:(NSString*)iconPath;
// Returns a UNNotificationCategory with the specified buttons. Needs to be
// called after setNotificationId is.
- (UNNotificationCategory*)buildCategory;
// Returns a notification ready to be displayed out of the provided
// |notificationData|.
- (UNMutableNotificationContent*)buildUserNotification;
......
......@@ -19,6 +19,104 @@
forKey:notification_constants::kNotificationIconPath];
}
- (UNNotificationCategory*)buildCategory {
DCHECK(
[_notificationData objectForKey:notification_constants::kNotificationId]);
DCHECK([_notificationData
objectForKey:notification_constants::kNotificationHasSettingsButton]);
NSMutableArray* buttonsArray = [NSMutableArray arrayWithCapacity:4];
// Extensions don't have a settings button.
NSNumber* showSettingsButton = [_notificationData
objectForKey:notification_constants::kNotificationHasSettingsButton];
BOOL settingsButton = [showSettingsButton boolValue];
UNNotificationAction* closeButton = [UNNotificationAction
actionWithIdentifier:notification_constants::kNotificationCloseButtonTag
title:[_notificationData
objectForKey:notification_constants::
kNotificationCloseButtonTag]
options:UNNotificationActionOptionNone];
[buttonsArray addObject:closeButton];
if ([_notificationData
objectForKey:notification_constants::kNotificationButtonOne]) {
UNNotificationAction* buttonOne = [UNNotificationAction
actionWithIdentifier:notification_constants::kNotificationButtonOne
title:[_notificationData
objectForKey:notification_constants::
kNotificationButtonOne]
options:UNNotificationActionOptionNone];
[buttonsArray addObject:buttonOne];
}
if ([_notificationData
objectForKey:notification_constants::kNotificationButtonTwo]) {
UNNotificationAction* buttonTwo = [UNNotificationAction
actionWithIdentifier:notification_constants::kNotificationButtonTwo
title:[_notificationData
objectForKey:notification_constants::
kNotificationButtonTwo]
options:UNNotificationActionOptionNone];
[buttonsArray addObject:buttonTwo];
}
if (settingsButton) {
UNNotificationAction* settingsButton = [UNNotificationAction
actionWithIdentifier:notification_constants::
kNotificationSettingsButtonTag
title:
[_notificationData
objectForKey:notification_constants::
kNotificationSettingsButtonTag]
options:UNNotificationActionOptionNone];
[buttonsArray addObject:settingsButton];
}
// If there are only 2 buttons [Close, button] then the actions array need to
// be set as [button, Close] so that close is on top. This is to safeguard the
// order of the buttons in case respondsToSelector:@selector(alternateAction)
// were to return false.
if ([buttonsArray count] == 2) {
// Remove the close button and move it to the end of the array
[buttonsArray removeObject:closeButton];
[buttonsArray addObject:closeButton];
}
UNNotificationCategory* category = [UNNotificationCategory
categoryWithIdentifier:
[_notificationData
objectForKey:notification_constants::kNotificationId]
actions:buttonsArray
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
[_notificationData
setObject:[_notificationData
objectForKey:notification_constants::kNotificationId]
forKey:notification_constants::kNotificationCategoryIdentifier];
// This uses a private API to make sure the close button is always visible in
// both alerts and banners, and modifies its content so that it is consistent
// with the rest of the notification buttons. Otherwise, the text inside the
// close button will come from the Apple API
if ([category respondsToSelector:@selector(alternateAction)]) {
[buttonsArray removeObject:closeButton];
[category setValue:buttonsArray forKey:@"actions"];
[category setValue:closeButton forKey:@"_alternateAction"];
}
// This uses a private API to change the text of the actions menu title so
// that it is consistent with the rest of the notification buttons
if ([category respondsToSelector:@selector(actionsMenuTitle)]) {
[category setValue:[_notificationData
objectForKey:notification_constants::
kNotificationOptionsButtonTag]
forKey:@"_actionsMenuTitle"];
}
return category;
}
- (UNMutableNotificationContent*)buildUserNotification {
base::scoped_nsobject<UNMutableNotificationContent> toast(
[[UNMutableNotificationContent alloc] init]);
......@@ -94,6 +192,14 @@
if (attachment != nil)
[toast setAttachments:@[ attachment ]];
}
// Category
if ([_notificationData objectForKey:notification_constants::
kNotificationCategoryIdentifier]) {
[toast setCategoryIdentifier:
[_notificationData
objectForKey:notification_constants::
kNotificationCategoryIdentifier]];
}
[toast setUserInfo:@{
notification_constants::kNotificationOrigin : origin,
......
......@@ -25,7 +25,9 @@ API_AVAILABLE(macosx(10.14))
base::scoped_nsobject<UNNotificationBuilder> NewTestBuilder(
NotificationHandler::Type type) {
base::scoped_nsobject<UNNotificationBuilder> builder(
[[UNNotificationBuilder alloc] init]);
[[UNNotificationBuilder alloc] initWithCloseLabel:@"Close"
optionsLabel:@"Options"
settingsLabel:@"Settings"]);
[builder setNotificationId:@"notificationId"];
[builder setProfileId:@"profileId"];
[builder setIncognito:false];
......@@ -52,6 +54,244 @@ TEST(UNNotificationBuilderMacTest, TestNotificationData) {
}
}
TEST(UNNotificationBuilderMacTest, TestNotificationNoButtons) {
if (@available(macOS 10.14, *)) {
base::scoped_nsobject<UNNotificationBuilder> builder =
NewTestBuilder(NotificationHandler::Type::WEB_NON_PERSISTENT);
[builder setShowSettingsButton:true];
UNNotificationCategory* category = [builder buildCategory];
// Test contents of the category
if ([category respondsToSelector:@selector(alternateAction)]) {
EXPECT_EQ("Close", base::SysNSStringToUTF8([[category
valueForKey:@"_alternateAction"] title]));
EXPECT_EQ(base::SysNSStringToUTF8(
notification_constants::kNotificationCloseButtonTag),
base::SysNSStringToUTF8(
[[category valueForKey:@"_alternateAction"] identifier]));
EXPECT_EQ(1ul, [[category actions] count]);
} else {
EXPECT_EQ("Close", base::SysNSStringToUTF8(
[[[category actions] firstObject] title]));
EXPECT_EQ(base::SysNSStringToUTF8(
notification_constants::kNotificationCloseButtonTag),
base::SysNSStringToUTF8(
[[[category actions] firstObject] identifier]));
EXPECT_EQ(2ul, [[category actions] count]);
}
EXPECT_EQ("Settings",
base::SysNSStringToUTF8([[[category actions] lastObject] title]));
EXPECT_EQ(
base::SysNSStringToUTF8(
notification_constants::kNotificationSettingsButtonTag),
base::SysNSStringToUTF8([[[category actions] lastObject] identifier]));
UNMutableNotificationContent* content = [builder buildUserNotification];
EXPECT_EQ("notificationId",
base::SysNSStringToUTF8([content categoryIdentifier]));
}
}
TEST(UNNotificationBuilderMacTest, TestNotificationOneButton) {
if (@available(macOS 10.14, *)) {
base::scoped_nsobject<UNNotificationBuilder> builder =
NewTestBuilder(NotificationHandler::Type::WEB_NON_PERSISTENT);
[builder setButtons:@"Button1" secondaryButton:@""];
[builder setShowSettingsButton:true];
UNNotificationCategory* category = [builder buildCategory];
// Test contents of the category
if ([category respondsToSelector:@selector(alternateAction)]) {
EXPECT_EQ("Close", base::SysNSStringToUTF8([[category
valueForKey:@"_alternateAction"] title]));
EXPECT_EQ(base::SysNSStringToUTF8(
notification_constants::kNotificationCloseButtonTag),
base::SysNSStringToUTF8(
[[category valueForKey:@"_alternateAction"] identifier]));
EXPECT_EQ(2ul, [[category actions] count]);
} else {
EXPECT_EQ("Close", base::SysNSStringToUTF8(
[[[category actions] firstObject] title]));
EXPECT_EQ(base::SysNSStringToUTF8(
notification_constants::kNotificationCloseButtonTag),
base::SysNSStringToUTF8(
[[[category actions] firstObject] identifier]));
EXPECT_EQ(3ul, [[category actions] count]);
}
EXPECT_EQ("Button1",
base::SysNSStringToUTF8([[category actions][0] title]));
EXPECT_EQ(
base::SysNSStringToUTF8(notification_constants::kNotificationButtonOne),
base::SysNSStringToUTF8([[category actions][0] identifier]));
EXPECT_EQ("Settings",
base::SysNSStringToUTF8([[[category actions] lastObject] title]));
EXPECT_EQ(
base::SysNSStringToUTF8(
notification_constants::kNotificationSettingsButtonTag),
base::SysNSStringToUTF8([[[category actions] lastObject] identifier]));
if ([category respondsToSelector:@selector(actionsMenuTitle)]) {
EXPECT_EQ("Options", base::SysNSStringToUTF8(
[category valueForKey:@"_actionsMenuTitle"]));
}
UNMutableNotificationContent* content = [builder buildUserNotification];
EXPECT_EQ("notificationId",
base::SysNSStringToUTF8([content categoryIdentifier]));
}
}
TEST(UNNotificationBuilderMacTest, TestNotificationTwoButtons) {
if (@available(macOS 10.14, *)) {
base::scoped_nsobject<UNNotificationBuilder> builder =
NewTestBuilder(NotificationHandler::Type::WEB_NON_PERSISTENT);
[builder setButtons:@"Button1" secondaryButton:@"Button2"];
[builder setShowSettingsButton:true];
UNNotificationCategory* category = [builder buildCategory];
// Test contents of the category
if ([category respondsToSelector:@selector(alternateAction)]) {
EXPECT_EQ("Close", base::SysNSStringToUTF8([[category
valueForKey:@"_alternateAction"] title]));
EXPECT_EQ(base::SysNSStringToUTF8(
notification_constants::kNotificationCloseButtonTag),
base::SysNSStringToUTF8(
[[category valueForKey:@"_alternateAction"] identifier]));
EXPECT_EQ(3ul, [[category actions] count]);
} else {
EXPECT_EQ("Close", base::SysNSStringToUTF8(
[[[category actions] firstObject] title]));
EXPECT_EQ(base::SysNSStringToUTF8(
notification_constants::kNotificationCloseButtonTag),
base::SysNSStringToUTF8(
[[[category actions] firstObject] identifier]));
EXPECT_EQ(4ul, [[category actions] count]);
}
EXPECT_EQ("Button1",
base::SysNSStringToUTF8([[category actions][0] title]));
EXPECT_EQ(
base::SysNSStringToUTF8(notification_constants::kNotificationButtonOne),
base::SysNSStringToUTF8([[category actions][0] identifier]));
EXPECT_EQ("Button2",
base::SysNSStringToUTF8([[category actions][1] title]));
EXPECT_EQ(
base::SysNSStringToUTF8(notification_constants::kNotificationButtonTwo),
base::SysNSStringToUTF8([[category actions][1] identifier]));
EXPECT_EQ("Settings",
base::SysNSStringToUTF8([[[category actions] lastObject] title]));
EXPECT_EQ(
base::SysNSStringToUTF8(
notification_constants::kNotificationSettingsButtonTag),
base::SysNSStringToUTF8([[[category actions] lastObject] identifier]));
if ([category respondsToSelector:@selector(actionsMenuTitle)]) {
EXPECT_EQ("Options", base::SysNSStringToUTF8(
[category valueForKey:@"_actionsMenuTitle"]));
}
UNMutableNotificationContent* content = [builder buildUserNotification];
EXPECT_EQ("notificationId",
base::SysNSStringToUTF8([content categoryIdentifier]));
EXPECT_EQ(0ul, [[content attachments] count]);
}
}
TEST(UNNotificationBuilderMacTest, TestNotificationExtensionNoButtons) {
if (@available(macOS 10.14, *)) {
base::scoped_nsobject<UNNotificationBuilder> builder =
NewTestBuilder(NotificationHandler::Type::EXTENSION);
UNNotificationCategory* category = [builder buildCategory];
// Test contents of the category
if ([category respondsToSelector:@selector(alternateAction)]) {
EXPECT_EQ("Close", base::SysNSStringToUTF8([[category
valueForKey:@"_alternateAction"] title]));
EXPECT_EQ(base::SysNSStringToUTF8(
notification_constants::kNotificationCloseButtonTag),
base::SysNSStringToUTF8(
[[category valueForKey:@"_alternateAction"] identifier]));
EXPECT_EQ(0ul, [[category actions] count]);
} else {
EXPECT_EQ("Close", base::SysNSStringToUTF8(
[[[category actions] firstObject] title]));
EXPECT_EQ(base::SysNSStringToUTF8(
notification_constants::kNotificationCloseButtonTag),
base::SysNSStringToUTF8(
[[[category actions] firstObject] identifier]));
EXPECT_EQ(1ul, [[category actions] count]);
}
UNMutableNotificationContent* content = [builder buildUserNotification];
EXPECT_EQ("notificationId",
base::SysNSStringToUTF8([content categoryIdentifier]));
}
}
TEST(UNNotificationBuilderMacTest, TestNotificationExtensionTwoButtons) {
if (@available(macOS 10.14, *)) {
base::scoped_nsobject<UNNotificationBuilder> builder =
NewTestBuilder(NotificationHandler::Type::EXTENSION);
[builder setButtons:@"Button1" secondaryButton:@"Button2"];
UNNotificationCategory* category = [builder buildCategory];
// Test contents of the category
if ([category respondsToSelector:@selector(alternateAction)]) {
EXPECT_EQ("Close", base::SysNSStringToUTF8([[category
valueForKey:@"_alternateAction"] title]));
EXPECT_EQ(base::SysNSStringToUTF8(
notification_constants::kNotificationCloseButtonTag),
base::SysNSStringToUTF8(
[[category valueForKey:@"_alternateAction"] identifier]));
EXPECT_EQ(2ul, [[category actions] count]);
} else {
EXPECT_EQ("Close", base::SysNSStringToUTF8(
[[[category actions] firstObject] title]));
EXPECT_EQ(base::SysNSStringToUTF8(
notification_constants::kNotificationCloseButtonTag),
base::SysNSStringToUTF8(
[[[category actions] firstObject] identifier]));
EXPECT_EQ(3ul, [[category actions] count]);
}
EXPECT_EQ("Button1",
base::SysNSStringToUTF8([[category actions][0] title]));
EXPECT_EQ(
base::SysNSStringToUTF8(notification_constants::kNotificationButtonOne),
base::SysNSStringToUTF8([[category actions][0] identifier]));
EXPECT_EQ("Button2",
base::SysNSStringToUTF8([[[category actions] lastObject] title]));
EXPECT_EQ(
base::SysNSStringToUTF8(notification_constants::kNotificationButtonTwo),
base::SysNSStringToUTF8([[[category actions] lastObject] identifier]));
if ([category respondsToSelector:@selector(actionsMenuTitle)]) {
EXPECT_EQ("Options", base::SysNSStringToUTF8(
[category valueForKey:@"_actionsMenuTitle"]));
}
UNMutableNotificationContent* content = [builder buildUserNotification];
EXPECT_EQ("notificationId",
base::SysNSStringToUTF8([content categoryIdentifier]));
EXPECT_EQ(0ul, [[content attachments] count]);
}
}
TEST(UNNotificationBuilderMacTest, TestNotificationDataMissingContextMessage) {
if (@available(macOS 10.14, *)) {
base::scoped_nsobject<UNNotificationBuilder> builder =
......
......@@ -58,6 +58,16 @@
isEqualToString:notification_constants::
kNotificationSettingsButtonTag]) {
operation = NotificationOperation::NOTIFICATION_SETTINGS;
} else if ([[response actionIdentifier]
isEqualToString:notification_constants::
kNotificationButtonOne]) {
operation = NotificationOperation::NOTIFICATION_CLICK;
buttonIndex = 0;
} else if ([[response actionIdentifier]
isEqualToString:notification_constants::
kNotificationButtonTwo]) {
operation = NotificationOperation::NOTIFICATION_CLICK;
buttonIndex = 1;
} else {
NOTREACHED();
}
......
......@@ -53,7 +53,9 @@ API_AVAILABLE(macosx(10.14))
base::scoped_nsobject<UNNotificationBuilder> NewTestBuilder(
NotificationHandler::Type type) {
base::scoped_nsobject<UNNotificationBuilder> builder(
[[UNNotificationBuilder alloc] init]);
[[UNNotificationBuilder alloc] initWithCloseLabel:@"Close"
optionsLabel:@"Options"
settingsLabel:@"Settings"]);
[builder setTitle:@"Title"];
[builder setSubTitle:@"https://www.moe.com"];
[builder setContextMessage:@"hey there"];
......@@ -210,3 +212,55 @@ TEST(UNNotificationResponseBuilderMacTest, TestNotificationSettingsButton) {
buttonIndex.intValue);
}
}
TEST(UNNotificationResponseBuilderMacTest, TestNotificationButtonOne) {
if (@available(macOS 10.14, *)) {
base::scoped_nsobject<UNNotificationBuilder> builder =
NewTestBuilder(NotificationHandler::Type::WEB_PERSISTENT);
UNMutableNotificationContent* content = [builder buildUserNotification];
base::scoped_nsobject<NSMutableDictionary> userInfo(
[[content userInfo] mutableCopy]);
FakeUNNotificationResponse* fakeResponse = CreateFakeResponse(userInfo);
fakeResponse.actionIdentifier =
notification_constants::kNotificationButtonOne;
NSDictionary* response = [UNNotificationResponseBuilder
buildDictionary:static_cast<UNNotificationResponse*>(fakeResponse)];
NSNumber* operation =
[response objectForKey:notification_constants::kNotificationOperation];
NSNumber* buttonIndex = [response
objectForKey:notification_constants::kNotificationButtonIndex];
EXPECT_EQ(static_cast<int>(NotificationOperation::NOTIFICATION_CLICK),
operation.intValue);
EXPECT_EQ(0, buttonIndex.intValue);
}
}
TEST(UNNotificationResponseBuilderMacTest, TestNotificationButtonTwo) {
if (@available(macOS 10.14, *)) {
base::scoped_nsobject<UNNotificationBuilder> builder =
NewTestBuilder(NotificationHandler::Type::WEB_PERSISTENT);
UNMutableNotificationContent* content = [builder buildUserNotification];
base::scoped_nsobject<NSMutableDictionary> userInfo(
[[content userInfo] mutableCopy]);
FakeUNNotificationResponse* fakeResponse = CreateFakeResponse(userInfo);
fakeResponse.actionIdentifier =
notification_constants::kNotificationButtonTwo;
NSDictionary* response = [UNNotificationResponseBuilder
buildDictionary:static_cast<UNNotificationResponse*>(fakeResponse)];
NSNumber* operation =
[response objectForKey:notification_constants::kNotificationOperation];
NSNumber* buttonIndex = [response
objectForKey:notification_constants::kNotificationButtonIndex];
EXPECT_EQ(static_cast<int>(NotificationOperation::NOTIFICATION_CLICK),
operation.intValue);
EXPECT_EQ(1, buttonIndex.intValue);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment