OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 |
5 #import "chrome/browser/web_applications/web_app_mac.h" | 5 #import "chrome/browser/web_applications/web_app_mac.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 | 8 |
9 #include <errno.h> | 9 #include <errno.h> |
10 #include <sys/xattr.h> | 10 #include <sys/xattr.h> |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 base::FilePath(const std::string& bundle_id)); | 47 base::FilePath(const std::string& bundle_id)); |
48 MOCK_CONST_METHOD0(RevealAppShimInFinder, void()); | 48 MOCK_CONST_METHOD0(RevealAppShimInFinder, void()); |
49 }; | 49 }; |
50 | 50 |
51 ShellIntegration::ShortcutInfo GetShortcutInfo() { | 51 ShellIntegration::ShortcutInfo GetShortcutInfo() { |
52 ShellIntegration::ShortcutInfo info; | 52 ShellIntegration::ShortcutInfo info; |
53 info.extension_id = "extensionid"; | 53 info.extension_id = "extensionid"; |
54 info.extension_path = base::FilePath("/fake/extension/path"); | 54 info.extension_path = base::FilePath("/fake/extension/path"); |
55 info.title = ASCIIToUTF16("Shortcut Title"); | 55 info.title = ASCIIToUTF16("Shortcut Title"); |
56 info.url = GURL("http://example.com/"); | 56 info.url = GURL("http://example.com/"); |
57 info.profile_path = base::FilePath("Profile 1"); | 57 info.profile_path = base::FilePath("user_data_dir").Append("Profile 1"); |
58 info.profile_name = "profile name"; | 58 info.profile_name = "profile name"; |
59 return info; | 59 return info; |
60 } | 60 } |
61 | 61 |
| 62 class WebAppShortcutCreatorTest : public testing::Test { |
| 63 protected: |
| 64 WebAppShortcutCreatorTest() {} |
| 65 |
| 66 virtual void SetUp() { |
| 67 EXPECT_TRUE(app_data_path_temp_dir_.CreateUniqueTempDir()); |
| 68 EXPECT_TRUE(destination_path_temp_dir_.CreateUniqueTempDir()); |
| 69 app_data_path_ = app_data_path_temp_dir_.path(); |
| 70 destination_path_ = destination_path_temp_dir_.path(); |
| 71 |
| 72 info_ = GetShortcutInfo(); |
| 73 shim_base_name_ = base::FilePath( |
| 74 info_.profile_path.BaseName().value() + |
| 75 " " + info_.extension_id + ".app"); |
| 76 internal_shim_path_ = app_data_path_.Append(shim_base_name_); |
| 77 shim_path_ = destination_path_.Append(shim_base_name_); |
| 78 } |
| 79 |
| 80 base::ScopedTempDir app_data_path_temp_dir_; |
| 81 base::ScopedTempDir destination_path_temp_dir_; |
| 82 base::FilePath app_data_path_; |
| 83 base::FilePath destination_path_; |
| 84 |
| 85 ShellIntegration::ShortcutInfo info_; |
| 86 base::FilePath shim_base_name_; |
| 87 base::FilePath internal_shim_path_; |
| 88 base::FilePath shim_path_; |
| 89 private: |
| 90 DISALLOW_COPY_AND_ASSIGN(WebAppShortcutCreatorTest); |
| 91 }; |
| 92 |
| 93 |
62 } // namespace | 94 } // namespace |
63 | 95 |
64 namespace web_app { | 96 namespace web_app { |
65 | 97 |
66 TEST(WebAppShortcutCreatorTest, CreateShortcuts) { | 98 TEST_F(WebAppShortcutCreatorTest, CreateShortcuts) { |
67 base::ScopedTempDir temp_app_data_path; | 99 NiceMock<WebAppShortcutCreatorMock> shortcut_creator(app_data_path_, info_); |
68 EXPECT_TRUE(temp_app_data_path.CreateUniqueTempDir()); | |
69 base::ScopedTempDir temp_dst_dir; | |
70 EXPECT_TRUE(temp_dst_dir.CreateUniqueTempDir()); | |
71 | |
72 ShellIntegration::ShortcutInfo info = GetShortcutInfo(); | |
73 | |
74 base::FilePath app_name( | |
75 info.profile_path.value() + " " + info.extension_id + ".app"); | |
76 base::FilePath app_in_app_data_path_path = | |
77 temp_app_data_path.path().Append(app_name); | |
78 base::FilePath dst_folder = temp_dst_dir.path(); | |
79 base::FilePath dst_path = dst_folder.Append(app_name); | |
80 | |
81 NiceMock<WebAppShortcutCreatorMock> shortcut_creator( | |
82 temp_app_data_path.path(), info); | |
83 EXPECT_CALL(shortcut_creator, GetDestinationPath()) | 100 EXPECT_CALL(shortcut_creator, GetDestinationPath()) |
84 .WillRepeatedly(Return(dst_folder)); | 101 .WillRepeatedly(Return(destination_path_)); |
85 EXPECT_CALL(shortcut_creator, RevealAppShimInFinder()); | 102 EXPECT_CALL(shortcut_creator, RevealAppShimInFinder()); |
86 | 103 |
87 EXPECT_TRUE(shortcut_creator.CreateShortcuts()); | 104 EXPECT_TRUE(shortcut_creator.CreateShortcuts()); |
88 EXPECT_TRUE(base::PathExists(app_in_app_data_path_path)); | 105 EXPECT_TRUE(base::PathExists(shim_path_)); |
89 EXPECT_TRUE(base::PathExists(dst_path)); | 106 EXPECT_TRUE(base::PathExists(destination_path_)); |
90 EXPECT_EQ(dst_path.BaseName(), shortcut_creator.GetShortcutName()); | 107 EXPECT_EQ(shim_base_name_, shortcut_creator.GetShortcutName()); |
91 | 108 |
92 base::FilePath plist_path = dst_path.Append("Contents").Append("Info.plist"); | 109 base::FilePath plist_path = |
| 110 shim_path_.Append("Contents").Append("Info.plist"); |
93 NSDictionary* plist = [NSDictionary dictionaryWithContentsOfFile: | 111 NSDictionary* plist = [NSDictionary dictionaryWithContentsOfFile: |
94 base::mac::FilePathToNSString(plist_path)]; | 112 base::mac::FilePathToNSString(plist_path)]; |
95 EXPECT_NSEQ(base::SysUTF8ToNSString(info.extension_id), | 113 EXPECT_NSEQ(base::SysUTF8ToNSString(info_.extension_id), |
96 [plist objectForKey:app_mode::kCrAppModeShortcutIDKey]); | 114 [plist objectForKey:app_mode::kCrAppModeShortcutIDKey]); |
97 EXPECT_NSEQ(base::SysUTF16ToNSString(info.title), | 115 EXPECT_NSEQ(base::SysUTF16ToNSString(info_.title), |
98 [plist objectForKey:app_mode::kCrAppModeShortcutNameKey]); | 116 [plist objectForKey:app_mode::kCrAppModeShortcutNameKey]); |
99 EXPECT_NSEQ(base::SysUTF8ToNSString(info.url.spec()), | 117 EXPECT_NSEQ(base::SysUTF8ToNSString(info_.url.spec()), |
100 [plist objectForKey:app_mode::kCrAppModeShortcutURLKey]); | 118 [plist objectForKey:app_mode::kCrAppModeShortcutURLKey]); |
101 | 119 |
102 // Make sure all values in the plist are actually filled in. | 120 // Make sure all values in the plist are actually filled in. |
103 for (id key in plist) { | 121 for (id key in plist) { |
104 id value = [plist valueForKey:key]; | 122 id value = [plist valueForKey:key]; |
105 if (!base::mac::ObjCCast<NSString>(value)) | 123 if (!base::mac::ObjCCast<NSString>(value)) |
106 continue; | 124 continue; |
107 | 125 |
108 EXPECT_EQ([value rangeOfString:@"@APP_"].location, NSNotFound) | 126 EXPECT_EQ([value rangeOfString:@"@APP_"].location, NSNotFound) |
109 << [key UTF8String] << ":" << [value UTF8String]; | 127 << [key UTF8String] << ":" << [value UTF8String]; |
110 } | 128 } |
111 } | 129 } |
112 | 130 |
113 TEST(WebAppShortcutCreatorTest, UpdateShortcuts) { | 131 TEST_F(WebAppShortcutCreatorTest, UpdateShortcuts) { |
114 base::ScopedTempDir temp_app_data_path; | 132 base::ScopedTempDir other_folder_temp_dir; |
115 EXPECT_TRUE(temp_app_data_path.CreateUniqueTempDir()); | 133 EXPECT_TRUE(other_folder_temp_dir.CreateUniqueTempDir()); |
116 base::ScopedTempDir temp_dst_dir; | 134 base::FilePath other_folder = other_folder_temp_dir.path(); |
117 EXPECT_TRUE(temp_dst_dir.CreateUniqueTempDir()); | 135 base::FilePath other_shim_path = other_folder.Append(shim_base_name_); |
118 base::ScopedTempDir temp_dst_dir_other; | |
119 EXPECT_TRUE(temp_dst_dir_other.CreateUniqueTempDir()); | |
120 | 136 |
121 ShellIntegration::ShortcutInfo info = GetShortcutInfo(); | 137 NiceMock<WebAppShortcutCreatorMock> shortcut_creator(app_data_path_, info_); |
122 | |
123 base::FilePath app_name( | |
124 info.profile_path.value() + " " + info.extension_id + ".app"); | |
125 base::FilePath app_in_app_data_path_path = | |
126 temp_app_data_path.path().Append(app_name); | |
127 base::FilePath dst_folder = temp_dst_dir.path(); | |
128 base::FilePath other_folder = temp_dst_dir_other.path(); | |
129 | |
130 NiceMock<WebAppShortcutCreatorMock> shortcut_creator( | |
131 temp_app_data_path.path(), info); | |
132 EXPECT_CALL(shortcut_creator, GetDestinationPath()) | 138 EXPECT_CALL(shortcut_creator, GetDestinationPath()) |
133 .WillRepeatedly(Return(dst_folder)); | 139 .WillRepeatedly(Return(destination_path_)); |
134 | 140 |
135 std::string expected_bundle_id = kFakeChromeBundleId; | 141 std::string expected_bundle_id = kFakeChromeBundleId; |
136 expected_bundle_id += ".app.Profile-1-" + info.extension_id; | 142 expected_bundle_id += ".app.Profile-1-" + info_.extension_id; |
137 EXPECT_CALL(shortcut_creator, GetAppBundleById(expected_bundle_id)) | 143 EXPECT_CALL(shortcut_creator, GetAppBundleById(expected_bundle_id)) |
138 .WillOnce(Return(other_folder.Append(app_name))); | 144 .WillOnce(Return(other_shim_path)); |
139 | 145 |
140 shortcut_creator.BuildShortcut(other_folder.Append(app_name)); | 146 EXPECT_TRUE(shortcut_creator.BuildShortcut(other_shim_path)); |
141 | 147 |
142 EXPECT_TRUE(base::DeleteFile( | 148 EXPECT_TRUE(base::DeleteFile(other_shim_path.Append("Contents"), true)); |
143 other_folder.Append(app_name).Append("Contents"), true)); | |
144 | 149 |
145 EXPECT_TRUE(shortcut_creator.UpdateShortcuts()); | 150 EXPECT_TRUE(shortcut_creator.UpdateShortcuts()); |
146 EXPECT_FALSE(base::PathExists(dst_folder.Append(app_name))); | 151 EXPECT_FALSE(base::PathExists(shim_path_)); |
147 EXPECT_TRUE(base::PathExists( | 152 EXPECT_TRUE(base::PathExists(other_shim_path.Append("Contents"))); |
148 other_folder.Append(app_name).Append("Contents"))); | |
149 | 153 |
150 // Also test case where GetAppBundleById fails. | 154 // Also test case where GetAppBundleById fails. |
151 EXPECT_CALL(shortcut_creator, GetAppBundleById(expected_bundle_id)) | 155 EXPECT_CALL(shortcut_creator, GetAppBundleById(expected_bundle_id)) |
152 .WillOnce(Return(base::FilePath())); | 156 .WillOnce(Return(base::FilePath())); |
153 | 157 |
154 shortcut_creator.BuildShortcut(other_folder.Append(app_name)); | 158 EXPECT_TRUE(shortcut_creator.BuildShortcut(other_shim_path)); |
155 | 159 |
156 EXPECT_TRUE(base::DeleteFile( | 160 EXPECT_TRUE(base::DeleteFile(other_shim_path.Append("Contents"), true)); |
157 other_folder.Append(app_name).Append("Contents"), true)); | |
158 | 161 |
159 EXPECT_FALSE(shortcut_creator.UpdateShortcuts()); | 162 EXPECT_FALSE(shortcut_creator.UpdateShortcuts()); |
160 EXPECT_FALSE(base::PathExists(dst_folder.Append(app_name))); | 163 EXPECT_FALSE(base::PathExists(shim_path_)); |
161 EXPECT_FALSE(base::PathExists( | 164 EXPECT_FALSE(base::PathExists(other_shim_path.Append("Contents"))); |
162 other_folder.Append(app_name).Append("Contents"))); | |
163 } | 165 } |
164 | 166 |
165 TEST(WebAppShortcutCreatorTest, CreateAppListShortcut) { | 167 TEST_F(WebAppShortcutCreatorTest, CreateAppListShortcut) { |
166 base::ScopedTempDir temp_dst_dir; | |
167 EXPECT_TRUE(temp_dst_dir.CreateUniqueTempDir()); | |
168 | |
169 ShellIntegration::ShortcutInfo info = GetShortcutInfo(); | |
170 | |
171 base::FilePath dst_folder = temp_dst_dir.path(); | |
172 | |
173 // With an empty |profile_name|, the shortcut path should not have the profile | 168 // With an empty |profile_name|, the shortcut path should not have the profile |
174 // directory prepended to the extension id on the app bundle name. | 169 // directory prepended to the extension id on the app bundle name. |
175 info.profile_name.clear(); | 170 info_.profile_name.clear(); |
176 base::FilePath dst_path = dst_folder.Append(info.extension_id + ".app"); | 171 base::FilePath dst_path = |
| 172 destination_path_.Append(info_.extension_id + ".app"); |
177 | 173 |
178 NiceMock<WebAppShortcutCreatorMock> shortcut_creator(base::FilePath(), info); | 174 NiceMock<WebAppShortcutCreatorMock> shortcut_creator(base::FilePath(), info_); |
179 EXPECT_CALL(shortcut_creator, GetDestinationPath()) | 175 EXPECT_CALL(shortcut_creator, GetDestinationPath()) |
180 .WillRepeatedly(Return(dst_folder)); | 176 .WillRepeatedly(Return(destination_path_)); |
181 EXPECT_EQ(dst_path.BaseName(), shortcut_creator.GetShortcutName()); | 177 EXPECT_EQ(dst_path.BaseName(), shortcut_creator.GetShortcutName()); |
182 } | 178 } |
183 | 179 |
184 TEST(WebAppShortcutCreatorTest, RunShortcut) { | 180 TEST_F(WebAppShortcutCreatorTest, RunShortcut) { |
185 base::ScopedTempDir temp_app_data_path; | 181 NiceMock<WebAppShortcutCreatorMock> shortcut_creator(app_data_path_, info_); |
186 EXPECT_TRUE(temp_app_data_path.CreateUniqueTempDir()); | |
187 base::ScopedTempDir temp_dst_dir; | |
188 EXPECT_TRUE(temp_dst_dir.CreateUniqueTempDir()); | |
189 | |
190 ShellIntegration::ShortcutInfo info = GetShortcutInfo(); | |
191 | |
192 base::FilePath dst_folder = temp_dst_dir.path(); | |
193 base::FilePath dst_path = dst_folder.Append( | |
194 info.profile_path.value() + " " + info.extension_id + ".app"); | |
195 | |
196 NiceMock<WebAppShortcutCreatorMock> shortcut_creator( | |
197 temp_app_data_path.path(), info); | |
198 EXPECT_CALL(shortcut_creator, GetDestinationPath()) | 182 EXPECT_CALL(shortcut_creator, GetDestinationPath()) |
199 .WillRepeatedly(Return(dst_folder)); | 183 .WillRepeatedly(Return(destination_path_)); |
200 EXPECT_CALL(shortcut_creator, RevealAppShimInFinder()); | 184 EXPECT_CALL(shortcut_creator, RevealAppShimInFinder()); |
201 | 185 |
202 EXPECT_TRUE(shortcut_creator.CreateShortcuts()); | 186 EXPECT_TRUE(shortcut_creator.CreateShortcuts()); |
203 EXPECT_TRUE(base::PathExists(dst_path)); | 187 EXPECT_TRUE(base::PathExists(shim_path_)); |
204 | 188 |
205 ssize_t status = getxattr( | 189 ssize_t status = getxattr( |
206 dst_path.value().c_str(), "com.apple.quarantine", NULL, 0, 0, 0); | 190 shim_path_.value().c_str(), "com.apple.quarantine", NULL, 0, 0, 0); |
207 EXPECT_EQ(-1, status); | 191 EXPECT_EQ(-1, status); |
208 EXPECT_EQ(ENOATTR, errno); | 192 EXPECT_EQ(ENOATTR, errno); |
209 } | 193 } |
210 | 194 |
211 TEST(WebAppShortcutCreatorTest, CreateFailure) { | 195 TEST_F(WebAppShortcutCreatorTest, CreateFailure) { |
212 base::ScopedTempDir temp_app_data_path; | 196 base::FilePath non_existent_path = |
213 EXPECT_TRUE(temp_app_data_path.CreateUniqueTempDir()); | 197 destination_path_.Append("not-existent").Append("name.app"); |
214 base::ScopedTempDir temp_dst_dir; | |
215 EXPECT_TRUE(temp_dst_dir.CreateUniqueTempDir()); | |
216 | 198 |
217 base::FilePath non_existent_path = | 199 NiceMock<WebAppShortcutCreatorMock> shortcut_creator(app_data_path_, info_); |
218 temp_dst_dir.path().Append("not-existent").Append("name.app"); | |
219 | |
220 NiceMock<WebAppShortcutCreatorMock> shortcut_creator( | |
221 temp_app_data_path.path(), GetShortcutInfo()); | |
222 EXPECT_CALL(shortcut_creator, GetDestinationPath()) | 200 EXPECT_CALL(shortcut_creator, GetDestinationPath()) |
223 .WillRepeatedly(Return(non_existent_path)); | 201 .WillRepeatedly(Return(non_existent_path)); |
224 EXPECT_FALSE(shortcut_creator.CreateShortcuts()); | 202 EXPECT_FALSE(shortcut_creator.CreateShortcuts()); |
225 } | 203 } |
226 | 204 |
227 TEST(WebAppShortcutCreatorTest, UpdateIcon) { | 205 TEST_F(WebAppShortcutCreatorTest, UpdateIcon) { |
228 base::ScopedTempDir temp_app_data_path; | |
229 EXPECT_TRUE(temp_app_data_path.CreateUniqueTempDir()); | |
230 base::ScopedTempDir temp_dst_dir; | |
231 EXPECT_TRUE(temp_dst_dir.CreateUniqueTempDir()); | |
232 base::FilePath dst_path = temp_dst_dir.path(); | |
233 | |
234 ShellIntegration::ShortcutInfo info = GetShortcutInfo(); | |
235 gfx::Image product_logo = | 206 gfx::Image product_logo = |
236 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 207 ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
237 IDR_PRODUCT_LOGO_32); | 208 IDR_PRODUCT_LOGO_32); |
238 info.favicon.Add(product_logo); | 209 info_.favicon.Add(product_logo); |
239 WebAppShortcutCreatorMock shortcut_creator(temp_app_data_path.path(), info); | 210 WebAppShortcutCreatorMock shortcut_creator(app_data_path_, info_); |
240 | 211 |
241 ASSERT_TRUE(shortcut_creator.UpdateIcon(dst_path)); | 212 ASSERT_TRUE(shortcut_creator.UpdateIcon(shim_path_)); |
242 base::FilePath icon_path = | 213 base::FilePath icon_path = |
243 dst_path.Append("Contents").Append("Resources").Append("app.icns"); | 214 shim_path_.Append("Contents").Append("Resources").Append("app.icns"); |
244 | 215 |
245 base::scoped_nsobject<NSImage> image([[NSImage alloc] | 216 base::scoped_nsobject<NSImage> image([[NSImage alloc] |
246 initWithContentsOfFile:base::mac::FilePathToNSString(icon_path)]); | 217 initWithContentsOfFile:base::mac::FilePathToNSString(icon_path)]); |
247 EXPECT_TRUE(image); | 218 EXPECT_TRUE(image); |
248 EXPECT_EQ(product_logo.Width(), [image size].width); | 219 EXPECT_EQ(product_logo.Width(), [image size].width); |
249 EXPECT_EQ(product_logo.Height(), [image size].height); | 220 EXPECT_EQ(product_logo.Height(), [image size].height); |
250 } | 221 } |
251 | 222 |
252 } // namespace web_app | 223 } // namespace web_app |
OLD | NEW |