Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 #import <objc/runtime.h> |
|
Robert Sesek
2016/10/13 16:47:32
nit: blank line before, and keep AppKit.h
| |
| 5 #import <AppKit/AppKit.h> | |
| 6 | 5 |
| 7 #include "base/mac/scoped_nsobject.h" | 6 #include "base/mac/scoped_nsobject.h" |
| 8 #include "chrome/browser/notifications/notification_common.h" | 7 #import "base/mac/scoped_objc_class_swizzler.h" |
| 8 #include "base/strings/utf_string_conversions.h" | |
| 9 #include "chrome/browser/notifications/notification.h" | |
| 9 #include "chrome/browser/notifications/notification_platform_bridge_mac.h" | 10 #include "chrome/browser/notifications/notification_platform_bridge_mac.h" |
| 11 #include "chrome/browser/notifications/notification_test_util.h" | |
| 12 #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" | |
| 10 #include "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h" | 13 #include "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h" |
| 11 #include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h" | 14 #include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h" |
| 12 #include "chrome/browser/ui/cocoa/notifications/notification_response_builder_ma c.h" | 15 #include "chrome/browser/ui/cocoa/notifications/notification_response_builder_ma c.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "third_party/ocmock/gtest_support.h" | |
|
Robert Sesek
2016/10/13 16:47:32
Remove for now.
Miguel Garcia
2016/10/14 10:58:13
Done.
| |
| 18 #include "url/gurl.h" | |
| 14 | 19 |
| 15 namespace { | 20 namespace { |
| 16 | 21 |
| 17 NSMutableDictionary* BuildDefaultNotificationResponse() { | 22 NSMutableDictionary* BuildDefaultNotificationResponse() { |
| 18 base::scoped_nsobject<NotificationBuilder> builder( | 23 base::scoped_nsobject<NotificationBuilder> builder( |
| 19 [[NotificationBuilder alloc] initWithCloseLabel:@"Close" | 24 [[NotificationBuilder alloc] initWithCloseLabel:@"Close" |
| 20 optionsLabel:@"Options" | 25 optionsLabel:@"Options" |
| 21 settingsLabel:@"Settings"]); | 26 settingsLabel:@"Settings"]); |
| 22 [builder setTitle:@"Title"]; | 27 [builder setTitle:@"Title"]; |
| 23 [builder setSubTitle:@"https://www.miguel.com"]; | 28 [builder setSubTitle:@"https://www.miguel.com"]; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 34 numberWithInt:NotificationCommon::PERSISTENT]]; | 39 numberWithInt:NotificationCommon::PERSISTENT]]; |
| 35 | 40 |
| 36 NSUserNotification* notification = [builder buildUserNotification]; | 41 NSUserNotification* notification = [builder buildUserNotification]; |
| 37 return [NSMutableDictionary | 42 return [NSMutableDictionary |
| 38 dictionaryWithDictionary:[NotificationResponseBuilder | 43 dictionaryWithDictionary:[NotificationResponseBuilder |
| 39 buildDictionary:notification]]; | 44 buildDictionary:notification]]; |
| 40 } | 45 } |
| 41 | 46 |
| 42 } // namespace | 47 } // namespace |
| 43 | 48 |
| 44 TEST(NotificationPlatformBridgeMacTest, TestNotificationValidResponse) { | 49 class NotificationPlatformBridgeMacTest : public CocoaTest { |
| 50 protected: | |
| 51 std::unique_ptr<Notification> CreateNotification(const char* title, | |
| 52 const char* subtitle, | |
| 53 const char* origin, | |
| 54 const char* button1, | |
| 55 const char* button2) { | |
| 56 message_center::RichNotificationData optional_fields; | |
| 57 optional_fields.context_message = base::UTF8ToUTF16(origin); | |
| 58 if (strlen(button1)) { | |
|
Robert Sesek
2016/10/13 16:47:32
Why not just use nullptrs instead of strlen?
Miguel Garcia
2016/10/14 10:58:13
Changed to nullptrs, I kind of prefer empty string
| |
| 59 optional_fields.buttons.push_back( | |
| 60 message_center::ButtonInfo(base::UTF8ToUTF16(button1))); | |
| 61 if (strlen(button2)) { | |
| 62 optional_fields.buttons.push_back( | |
| 63 message_center::ButtonInfo(base::UTF8ToUTF16(button2))); | |
| 64 } | |
| 65 } | |
| 66 | |
| 67 NotificationDelegate* delegate(new MockNotificationDelegate("id1")); | |
|
Robert Sesek
2016/10/13 16:47:32
Who owns this? Should this be a scoped_refptr<>?
Miguel Garcia
2016/10/14 10:58:13
The notification object owns it though a scoped_re
Robert Sesek
2016/10/14 14:21:26
I think it should just be wrapped in a scoped_refp
| |
| 68 GURL url = GURL(origin); | |
| 69 | |
| 70 std::unique_ptr<Notification> notification(new Notification( | |
| 71 message_center::NOTIFICATION_TYPE_SIMPLE, base::UTF8ToUTF16(title), | |
| 72 base::UTF8ToUTF16(subtitle), gfx::Image(), | |
| 73 message_center::NotifierId(url), base::UTF8ToUTF16("Notifier's Name"), | |
| 74 url, "id1", optional_fields, delegate)); | |
| 75 | |
| 76 return notification; | |
| 77 } | |
| 78 }; | |
| 79 | |
| 80 TEST_F(NotificationPlatformBridgeMacTest, TestNotificationVerifyValidResponse) { | |
| 45 NSDictionary* response = BuildDefaultNotificationResponse(); | 81 NSDictionary* response = BuildDefaultNotificationResponse(); |
| 46 EXPECT_TRUE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); | 82 EXPECT_TRUE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); |
| 47 } | 83 } |
| 48 | 84 |
| 49 TEST(NotificationPlatformBridgeMacTest, TestNotificationUnknownType) { | 85 TEST_F(NotificationPlatformBridgeMacTest, TestNotificationUnknownType) { |
| 50 NSMutableDictionary* response = BuildDefaultNotificationResponse(); | 86 NSMutableDictionary* response = BuildDefaultNotificationResponse(); |
| 51 [response setValue:[NSNumber numberWithInt:210581] | 87 [response setValue:[NSNumber numberWithInt:210581] |
| 52 forKey:notification_constants::kNotificationType]; | 88 forKey:notification_constants::kNotificationType]; |
| 53 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); | 89 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); |
| 54 } | 90 } |
| 55 | 91 |
| 56 TEST(NotificationPlatformBridgeMacTest, TestNotificationUnknownOperation) { | 92 TEST_F(NotificationPlatformBridgeMacTest, |
| 93 TestNotificationVerifyUnknownOperation) { | |
| 57 NSMutableDictionary* response = BuildDefaultNotificationResponse(); | 94 NSMutableDictionary* response = BuildDefaultNotificationResponse(); |
| 58 [response setValue:[NSNumber numberWithInt:40782] | 95 [response setValue:[NSNumber numberWithInt:40782] |
| 59 forKey:notification_constants::kNotificationOperation]; | 96 forKey:notification_constants::kNotificationOperation]; |
| 60 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); | 97 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); |
| 61 } | 98 } |
| 62 | 99 |
| 63 TEST(NotificationPlatformBridgeMacTest, TestNotificationMissingOperation) { | 100 TEST_F(NotificationPlatformBridgeMacTest, |
| 101 TestNotificationVerifyMissingOperation) { | |
| 64 NSMutableDictionary* response = BuildDefaultNotificationResponse(); | 102 NSMutableDictionary* response = BuildDefaultNotificationResponse(); |
| 65 [response removeObjectForKey:notification_constants::kNotificationOperation]; | 103 [response removeObjectForKey:notification_constants::kNotificationOperation]; |
| 66 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); | 104 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); |
| 67 } | 105 } |
| 68 | 106 |
| 69 TEST(NotificationPlatformBridgeMacTest, TestNotificationNoProfileId) { | 107 TEST_F(NotificationPlatformBridgeMacTest, TestNotificationVerifyNoProfileId) { |
| 70 NSMutableDictionary* response = BuildDefaultNotificationResponse(); | 108 NSMutableDictionary* response = BuildDefaultNotificationResponse(); |
| 71 [response removeObjectForKey:notification_constants::kNotificationProfileId]; | 109 [response removeObjectForKey:notification_constants::kNotificationProfileId]; |
| 72 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); | 110 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); |
| 73 } | 111 } |
| 74 | 112 |
| 75 TEST(NotificationPlatformBridgeMacTest, TestNotificationNoNotificationId) { | 113 TEST_F(NotificationPlatformBridgeMacTest, |
| 114 TestNotificationVerifyNoNotificationId) { | |
| 76 NSMutableDictionary* response = BuildDefaultNotificationResponse(); | 115 NSMutableDictionary* response = BuildDefaultNotificationResponse(); |
| 77 [response setValue:@"" forKey:notification_constants::kNotificationId]; | 116 [response setValue:@"" forKey:notification_constants::kNotificationId]; |
| 78 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); | 117 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); |
| 79 } | 118 } |
| 80 | 119 |
| 81 TEST(NotificationPlatformBridgeMacTest, TestNotificationInvalidButton) { | 120 TEST_F(NotificationPlatformBridgeMacTest, TestNotificationVerifyInvalidButton) { |
| 82 NSMutableDictionary* response = BuildDefaultNotificationResponse(); | 121 NSMutableDictionary* response = BuildDefaultNotificationResponse(); |
| 83 [response setValue:[NSNumber numberWithInt:-5] | 122 [response setValue:[NSNumber numberWithInt:-5] |
| 84 forKey:notification_constants::kNotificationButtonIndex]; | 123 forKey:notification_constants::kNotificationButtonIndex]; |
| 85 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); | 124 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); |
| 86 } | 125 } |
| 87 | 126 |
| 88 TEST(NotificationPlatformBridgeMacTest, TestNotificationMissingButtonIndex) { | 127 TEST_F(NotificationPlatformBridgeMacTest, |
| 128 TestNotificationVerifyMissingButtonIndex) { | |
| 89 NSMutableDictionary* response = BuildDefaultNotificationResponse(); | 129 NSMutableDictionary* response = BuildDefaultNotificationResponse(); |
| 90 [response | 130 [response |
| 91 removeObjectForKey:notification_constants::kNotificationButtonIndex]; | 131 removeObjectForKey:notification_constants::kNotificationButtonIndex]; |
| 92 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); | 132 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); |
| 93 } | 133 } |
| 94 | 134 |
| 95 TEST(NotificationPlatformBridgeMacTest, TestNotificationOrigin) { | 135 TEST_F(NotificationPlatformBridgeMacTest, TestNotificationVerifyOrigin) { |
| 96 NSMutableDictionary* response = BuildDefaultNotificationResponse(); | 136 NSMutableDictionary* response = BuildDefaultNotificationResponse(); |
| 97 [response setValue:@"invalidorigin" | 137 [response setValue:@"invalidorigin" |
| 98 forKey:notification_constants::kNotificationOrigin]; | 138 forKey:notification_constants::kNotificationOrigin]; |
| 99 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); | 139 EXPECT_FALSE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); |
| 100 | 140 |
| 101 // If however the origin is not present the response should be fine. | 141 // If however the origin is not present the response should be fine. |
| 102 [response removeObjectForKey:notification_constants::kNotificationOrigin]; | 142 [response removeObjectForKey:notification_constants::kNotificationOrigin]; |
| 103 EXPECT_TRUE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); | 143 EXPECT_TRUE(NotificationPlatformBridgeMac::VerifyNotificationData(response)); |
| 104 } | 144 } |
| 145 | |
| 146 // The usual [NSUSerNotificationCenter defaultNotificationCenter] constructor | |
| 147 // is not available in tests. The private constructor fortunatelly is. | |
| 148 @interface NSUserNotificationCenter (PrivateAPI) | |
| 149 + (NSUserNotificationCenter*)_centerForIdentifier:(NSString*)ident | |
| 150 type:(NSUInteger)type; | |
| 151 @end | |
| 152 | |
| 153 // Category to extend the notification center with different implementations | |
| 154 // of the deliverNotification selector which can be swizzled as part of the | |
| 155 // test. | |
| 156 // TODO(miguelg) replace this with OCMock once a version with support | |
| 157 // for dynamic properties is rolled out (crbug.com/622753). | |
| 158 @interface NSUserNotificationCenter (TestAdditions) | |
| 159 - (void)expectationsNoButtons:(NSUserNotification*)notification; | |
| 160 - (void)expectationsOneButton:(NSUserNotification*)notification; | |
| 161 @end | |
| 162 | |
| 163 @implementation NSUserNotificationCenter (TestAdditions) | |
| 164 | |
| 165 // Expectations for notifications with no buttons. | |
| 166 - (void)expectationsNoButtons:(NSUserNotification*)notification { | |
| 167 ASSERT_TRUE([[notification title] isEqualToString:@"Title"]); | |
|
Robert Sesek
2016/10/13 16:47:32
Use EXPECT_NSEQ if you want a little bit better fa
Miguel Garcia
2016/10/14 10:58:14
Done
| |
| 168 ASSERT_TRUE([[notification informativeText] isEqualToString:@"Context"]); | |
| 169 ASSERT_TRUE([[notification subtitle] isEqualToString:@"https://gmail.com"]); | |
| 170 ASSERT_TRUE([[notification otherButtonTitle] isEqualToString:@"Close"]); | |
| 171 ASSERT_TRUE([[notification actionButtonTitle] isEqualToString:@"Settings"]); | |
| 172 } | |
| 173 | |
| 174 // Expectations for notifications with one button. | |
| 175 - (void)expectationsOneButton:(NSUserNotification*)notification { | |
| 176 ASSERT_TRUE([[notification title] isEqualToString:@"Title"]); | |
| 177 ASSERT_TRUE([[notification informativeText] isEqualToString:@"Context"]); | |
| 178 ASSERT_TRUE([[notification subtitle] isEqualToString:@"https://gmail.com"]); | |
| 179 ASSERT_TRUE([[notification otherButtonTitle] isEqualToString:@"Close"]); | |
| 180 ASSERT_TRUE([[notification actionButtonTitle] isEqualToString:@"Options"]); | |
| 181 } | |
| 182 | |
| 183 @end | |
| 184 | |
| 185 TEST_F(NotificationPlatformBridgeMacTest, TestDisplayNoButtons) { | |
| 186 base::scoped_nsobject<NSUserNotificationCenter> notification_center( | |
| 187 [NSUserNotificationCenter _centerForIdentifier:@"" type:0x0]); | |
| 188 base::mac::ScopedObjCClassSwizzler swizzler( | |
| 189 [notification_center class], @selector(deliverNotification:), | |
| 190 @selector(expectationsNoButtons:)); | |
| 191 | |
| 192 std::unique_ptr<Notification> notification = | |
| 193 CreateNotification("Title", "Context", "https://gmail.com", "", ""); | |
| 194 std::unique_ptr<NotificationPlatformBridgeMac> bridge( | |
| 195 new NotificationPlatformBridgeMac(notification_center)); | |
| 196 bridge->Display(NotificationCommon::PERSISTENT, "notification_id", | |
| 197 "profile_id", false, *notification); | |
| 198 } | |
| 199 | |
| 200 TEST_F(NotificationPlatformBridgeMacTest, TestDisplayOneButton) { | |
| 201 std::unique_ptr<Notification> notification = CreateNotification( | |
| 202 "Title", "Context", "https://gmail.com", "Button 1", ""); | |
| 203 base::scoped_nsobject<NSUserNotificationCenter> notification_center( | |
| 204 [NSUserNotificationCenter _centerForIdentifier:@"" type:0x0]); | |
| 205 base::mac::ScopedObjCClassSwizzler swizzler( | |
| 206 [notification_center class], @selector(deliverNotification:), | |
| 207 @selector(expectationsOneButton:)); | |
| 208 std::unique_ptr<NotificationPlatformBridgeMac> bridge( | |
| 209 new NotificationPlatformBridgeMac(notification_center)); | |
| 210 bridge->Display(NotificationCommon::PERSISTENT, "notification_id", | |
| 211 "profile_id", false, *notification); | |
| 212 } | |
| OLD | NEW |