| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 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 <memory> | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/memory/ptr_util.h" | |
| 9 #include "base/metrics/user_metrics.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | |
| 11 #include "ios/chrome/browser/infobars/infobar_manager_impl.h" | |
| 12 #import "ios/chrome/browser/installation_notifier.h" | |
| 13 #include "ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h" | |
| 14 #import "ios/chrome/browser/native_app_launcher/native_app_navigation_controller
.h" | |
| 15 #import "ios/chrome/browser/web/chrome_web_test.h" | |
| 16 #include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.h" | |
| 17 #import "ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_
metadata.h" | |
| 18 #import "ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_
whitelist_manager.h" | |
| 19 #include "ios/public/provider/chrome/browser/test_chrome_browser_provider.h" | |
| 20 #import "testing/gtest_mac.h" | |
| 21 | |
| 22 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
| 23 #error "This file requires ARC support." | |
| 24 #endif | |
| 25 | |
| 26 @interface NativeAppNavigationController (Testing) | |
| 27 - (void)recordInfobarDisplayedOfType:(NativeAppControllerType)type | |
| 28 onLinkNavigation:(BOOL)isLinkNavigation; | |
| 29 - (NSMutableSet*)appsPossiblyBeingInstalled; | |
| 30 - (void)removeAppFromNotification:(NSNotification*)notification; | |
| 31 @end | |
| 32 | |
| 33 namespace { | |
| 34 | |
| 35 class FakeChromeBrowserProvider : public ios::TestChromeBrowserProvider { | |
| 36 public: | |
| 37 FakeChromeBrowserProvider(FakeNativeAppWhitelistManager* fake_manager) { | |
| 38 manager_ = fake_manager; | |
| 39 } | |
| 40 ~FakeChromeBrowserProvider() override {} | |
| 41 | |
| 42 id<NativeAppWhitelistManager> GetNativeAppWhitelistManager() const override { | |
| 43 return manager_; | |
| 44 } | |
| 45 | |
| 46 private: | |
| 47 id<NativeAppWhitelistManager> manager_; | |
| 48 }; | |
| 49 | |
| 50 class NativeAppNavigationControllerTest : public ChromeWebTest { | |
| 51 protected: | |
| 52 void SetUp() override { | |
| 53 ChromeWebTest::SetUp(); | |
| 54 controller_ = | |
| 55 [[NativeAppNavigationController alloc] initWithWebState:web_state()]; | |
| 56 | |
| 57 action_callback_ = | |
| 58 base::Bind(&NativeAppNavigationControllerTest::OnUserAction, | |
| 59 base::Unretained(this)); | |
| 60 base::AddActionCallback(action_callback_); | |
| 61 | |
| 62 handler_called_counter_ = 0; | |
| 63 } | |
| 64 | |
| 65 void TearDown() override { | |
| 66 base::RemoveActionCallback(action_callback_); | |
| 67 ChromeWebTest::TearDown(); | |
| 68 } | |
| 69 | |
| 70 void SetExpectedActionName(const std::string& action_name) { | |
| 71 expected_action_name_.reset(new std::string(action_name)); | |
| 72 } | |
| 73 | |
| 74 void OnUserAction(const std::string& action_name) { | |
| 75 EXPECT_EQ(*expected_action_name_, action_name); | |
| 76 handler_called_counter_++; | |
| 77 } | |
| 78 | |
| 79 void ExpectHandlerCalledAndReset(int number_of_calls) { | |
| 80 EXPECT_EQ(number_of_calls, handler_called_counter_); | |
| 81 handler_called_counter_ = 0; | |
| 82 } | |
| 83 | |
| 84 NativeAppNavigationController* controller_; | |
| 85 | |
| 86 // The callback to invoke when an action is recorded. | |
| 87 base::ActionCallback action_callback_; | |
| 88 std::unique_ptr<std::string> expected_action_name_; | |
| 89 int handler_called_counter_; | |
| 90 }; | |
| 91 | |
| 92 TEST_F(NativeAppNavigationControllerTest, TestConstructor) { | |
| 93 EXPECT_TRUE(controller_); | |
| 94 } | |
| 95 | |
| 96 TEST_F(NativeAppNavigationControllerTest, TestUMA) { | |
| 97 SetExpectedActionName("MobileGALInstallInfoBarLinkNavigation"); | |
| 98 [controller_ recordInfobarDisplayedOfType:NATIVE_APP_INSTALLER_CONTROLLER | |
| 99 onLinkNavigation:YES]; | |
| 100 ExpectHandlerCalledAndReset(1); | |
| 101 | |
| 102 SetExpectedActionName("MobileGALInstallInfoBarDirectNavigation"); | |
| 103 [controller_ recordInfobarDisplayedOfType:NATIVE_APP_INSTALLER_CONTROLLER | |
| 104 onLinkNavigation:NO]; | |
| 105 ExpectHandlerCalledAndReset(1); | |
| 106 | |
| 107 SetExpectedActionName("MobileGALLaunchInfoBar"); | |
| 108 [controller_ recordInfobarDisplayedOfType:NATIVE_APP_LAUNCHER_CONTROLLER | |
| 109 onLinkNavigation:YES]; | |
| 110 ExpectHandlerCalledAndReset(1); | |
| 111 [controller_ recordInfobarDisplayedOfType:NATIVE_APP_LAUNCHER_CONTROLLER | |
| 112 onLinkNavigation:NO]; | |
| 113 ExpectHandlerCalledAndReset(1); | |
| 114 | |
| 115 SetExpectedActionName("MobileGALOpenPolicyInfoBar"); | |
| 116 [controller_ recordInfobarDisplayedOfType:NATIVE_APP_OPEN_POLICY_CONTROLLER | |
| 117 onLinkNavigation:YES]; | |
| 118 ExpectHandlerCalledAndReset(1); | |
| 119 [controller_ recordInfobarDisplayedOfType:NATIVE_APP_OPEN_POLICY_CONTROLLER | |
| 120 onLinkNavigation:NO]; | |
| 121 ExpectHandlerCalledAndReset(1); | |
| 122 } | |
| 123 | |
| 124 // Tests presenting NativeAppInfoBar after page is loaded. | |
| 125 TEST_F(NativeAppNavigationControllerTest, NativeAppInfoBar) { | |
| 126 SetExpectedActionName("MobileGALInstallInfoBarDirectNavigation"); | |
| 127 InfoBarManagerImpl::CreateForWebState(web_state()); | |
| 128 | |
| 129 // Set up fake metadata. | |
| 130 FakeNativeAppWhitelistManager* fakeManager = | |
| 131 [[FakeNativeAppWhitelistManager alloc] init]; | |
| 132 IOSChromeScopedTestingChromeBrowserProvider provider( | |
| 133 base::MakeUnique<FakeChromeBrowserProvider>(fakeManager)); | |
| 134 FakeNativeAppMetadata* metadata = [[FakeNativeAppMetadata alloc] init]; | |
| 135 fakeManager.metadata = metadata; | |
| 136 metadata.appName = @"App"; | |
| 137 metadata.appId = @"App-ID"; | |
| 138 | |
| 139 // Load the page to trigger infobar presentation. | |
| 140 LoadHtml(@"<html><body></body></html>", GURL("http://test.com")); | |
| 141 | |
| 142 // Verify that infobar was presented | |
| 143 auto* infobar_manager = InfoBarManagerImpl::FromWebState(web_state()); | |
| 144 ASSERT_EQ(1U, infobar_manager->infobar_count()); | |
| 145 infobars::InfoBar* infobar = infobar_manager->infobar_at(0); | |
| 146 auto* delegate = infobar->delegate()->AsNativeAppInfoBarDelegate(); | |
| 147 ASSERT_TRUE(delegate); | |
| 148 | |
| 149 // Verify infobar appearance. | |
| 150 EXPECT_EQ("Open this page in the App app?", | |
| 151 base::UTF16ToUTF8(delegate->GetInstallText())); | |
| 152 EXPECT_EQ("Open this page in the App app?", | |
| 153 base::UTF16ToUTF8(delegate->GetLaunchText())); | |
| 154 EXPECT_EQ("Open in App", base::UTF16ToUTF8(delegate->GetOpenPolicyText())); | |
| 155 EXPECT_EQ("Just once", base::UTF16ToUTF8(delegate->GetOpenOnceText())); | |
| 156 EXPECT_EQ("Always", base::UTF16ToUTF8(delegate->GetOpenAlwaysText())); | |
| 157 EXPECT_NSEQ(@"App-ID", delegate->GetAppId()); | |
| 158 } | |
| 159 | |
| 160 TEST_F(NativeAppNavigationControllerTest, | |
| 161 TestRemovingAppFromListAfterInstallation) { | |
| 162 NSString* const kMapsAppName = @"Maps"; | |
| 163 NSString* const kMapsAppId = @"1"; | |
| 164 NSString* const kYoutubeAppName = @"Youtube"; | |
| 165 NSString* const kYoutubeAppId = @"2"; | |
| 166 | |
| 167 InstallationNotifier* installationNotifier = | |
| 168 [[InstallationNotifier alloc] init]; | |
| 169 | |
| 170 FakeNativeAppWhitelistManager* fakeManager = | |
| 171 [[FakeNativeAppWhitelistManager alloc] init]; | |
| 172 IOSChromeScopedTestingChromeBrowserProvider provider( | |
| 173 base::MakeUnique<FakeChromeBrowserProvider>(fakeManager)); | |
| 174 | |
| 175 FakeNativeAppMetadata* metadataMaps = [[FakeNativeAppMetadata alloc] init]; | |
| 176 [metadataMaps setAppName:kMapsAppName]; | |
| 177 [metadataMaps setAppId:kMapsAppId]; | |
| 178 ASSERT_TRUE(metadataMaps); | |
| 179 NSString* appIdMaps = [metadataMaps appId]; | |
| 180 NSNotification* notificationMaps = | |
| 181 [NSNotification notificationWithName:kMapsAppName | |
| 182 object:installationNotifier]; | |
| 183 | |
| 184 FakeNativeAppMetadata* metadataYouTube = [[FakeNativeAppMetadata alloc] init]; | |
| 185 [metadataYouTube setAppName:kYoutubeAppName]; | |
| 186 [metadataYouTube setAppId:kYoutubeAppId]; | |
| 187 | |
| 188 ASSERT_TRUE(metadataYouTube); | |
| 189 NSString* appIdYouTube = [metadataYouTube appId]; | |
| 190 NSNotification* notificationYouTube = | |
| 191 [NSNotification notificationWithName:kYoutubeAppName | |
| 192 object:installationNotifier]; | |
| 193 | |
| 194 DCHECK([[controller_ appsPossiblyBeingInstalled] count] == 0); | |
| 195 [[controller_ appsPossiblyBeingInstalled] addObject:appIdMaps]; | |
| 196 DCHECK([[controller_ appsPossiblyBeingInstalled] count] == 1); | |
| 197 [[controller_ appsPossiblyBeingInstalled] addObject:appIdYouTube]; | |
| 198 DCHECK([[controller_ appsPossiblyBeingInstalled] count] == 2); | |
| 199 [fakeManager setAppScheme:kMapsAppName]; | |
| 200 [controller_ removeAppFromNotification:notificationMaps]; | |
| 201 DCHECK([[controller_ appsPossiblyBeingInstalled] count] == 1); | |
| 202 [fakeManager setAppScheme:kYoutubeAppName]; | |
| 203 [controller_ removeAppFromNotification:notificationYouTube]; | |
| 204 DCHECK([[controller_ appsPossiblyBeingInstalled] count] == 0); | |
| 205 } | |
| 206 | |
| 207 } // namespace | |
| OLD | NEW |