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 |