OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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 "chrome/browser/conflicts/installed_programs_win.h" |
| 6 |
| 7 #include <map> |
| 8 #include <utility> |
| 9 |
| 10 #include "base/bind.h" |
| 11 #include "base/macros.h" |
| 12 #include "base/run_loop.h" |
| 13 #include "base/strings/string_util.h" |
| 14 #include "base/strings/stringprintf.h" |
| 15 #include "base/test/scoped_task_scheduler.h" |
| 16 #include "base/test/test_reg_util_win.h" |
| 17 #include "base/win/registry.h" |
| 18 #include "chrome/browser/conflicts/msi_util_win.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" |
| 20 |
| 21 namespace { |
| 22 |
| 23 struct FakeMSIProgram { |
| 24 base::string16 product_guid; |
| 25 bool is_system_component; |
| 26 bool is_microsoft_published; |
| 27 base::string16 display_name; |
| 28 base::string16 uninstall_string; |
| 29 std::vector<base::string16> components; |
| 30 }; |
| 31 |
| 32 class InstalledProgramsTest : public testing::Test { |
| 33 public: |
| 34 InstalledProgramsTest(); |
| 35 ~InstalledProgramsTest(); |
| 36 |
| 37 void SetUp() override; |
| 38 |
| 39 void SetUpFakeMSIProgram(const FakeMSIProgram& fake_msi_program); |
| 40 |
| 41 private: |
| 42 // Used to override the real GetMsiComponentPaths(). |
| 43 bool FakeGetMsiComponentPaths(const base::string16& product_guid, |
| 44 std::vector<base::string16>* component_paths); |
| 45 |
| 46 base::test::ScopedTaskScheduler scoped_task_scheduler_; |
| 47 registry_util::RegistryOverrideManager registry_override_manager_; |
| 48 |
| 49 // Override GetMsiComponentPaths(). The mapping from input to output is |
| 50 // managed by component_paths_map_. |
| 51 ScopedGetMsiComponentPathsOverride scoped_get_msi_component_paths_override_; |
| 52 std::map<base::string16, std::vector<base::string16>> component_paths_map_; |
| 53 |
| 54 DISALLOW_COPY_AND_ASSIGN(InstalledProgramsTest); |
| 55 }; |
| 56 |
| 57 InstalledProgramsTest::InstalledProgramsTest() |
| 58 : scoped_get_msi_component_paths_override_( |
| 59 base::Bind(&InstalledProgramsTest::FakeGetMsiComponentPaths, |
| 60 base::Unretained(this))) {} |
| 61 |
| 62 InstalledProgramsTest::~InstalledProgramsTest() = default; |
| 63 |
| 64 // ASSERT_NO_FATAL_FAILURE cannot be used in a constructor. |
| 65 void InstalledProgramsTest::SetUp() { |
| 66 ASSERT_NO_FATAL_FAILURE( |
| 67 registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE)); |
| 68 ASSERT_NO_FATAL_FAILURE( |
| 69 registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER)); |
| 70 } |
| 71 |
| 72 void InstalledProgramsTest::SetUpFakeMSIProgram( |
| 73 const FakeMSIProgram& fake_msi_program) { |
| 74 // Create the registry entry. |
| 75 const wchar_t kUninstallKeyPath[] = |
| 76 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; |
| 77 base::win::RegKey key( |
| 78 HKEY_CURRENT_USER, |
| 79 base::StringPrintf(L"%ls\\%ls", kUninstallKeyPath, |
| 80 fake_msi_program.product_guid.c_str()) |
| 81 .c_str(), |
| 82 KEY_WRITE); |
| 83 |
| 84 key.WriteValue(L"SystemComponent", |
| 85 fake_msi_program.is_system_component ? 1 : 0); |
| 86 key.WriteValue(L"UninstallString", fake_msi_program.uninstall_string.c_str()); |
| 87 if (fake_msi_program.is_microsoft_published) |
| 88 key.WriteValue(L"Publisher", L"Microsoft Corporation"); |
| 89 key.WriteValue(L"DisplayName", fake_msi_program.display_name.c_str()); |
| 90 |
| 91 component_paths_map_.insert(std::make_pair(fake_msi_program.product_guid, |
| 92 fake_msi_program.components)); |
| 93 } |
| 94 |
| 95 bool InstalledProgramsTest::FakeGetMsiComponentPaths( |
| 96 const base::string16& product_guid, |
| 97 std::vector<base::string16>* component_paths) { |
| 98 auto iter = component_paths_map_.find(product_guid); |
| 99 if (iter == component_paths_map_.end()) |
| 100 return false; |
| 101 |
| 102 *component_paths = iter->second; |
| 103 return true; |
| 104 } |
| 105 |
| 106 } // namespace |
| 107 |
| 108 TEST_F(InstalledProgramsTest, InstalledPrograms) { |
| 109 // Some properties that are used multiple time are defined here to avoid |
| 110 // duplication. |
| 111 const wchar_t kValidDisplayName[] = L"ADisplayName"; |
| 112 const wchar_t kValidUninstallString[] = L"AnUninstallString"; |
| 113 const wchar_t kValidComponentPath[] = L"c:\\a\\valid\\file\\name.dll"; |
| 114 |
| 115 std::pair<FakeMSIProgram, bool> kTestCases[] = { |
| 116 { |
| 117 { |
| 118 L"", // Empty GUID. |
| 119 false, |
| 120 false, |
| 121 kValidDisplayName, |
| 122 kValidUninstallString, |
| 123 { |
| 124 kValidComponentPath, |
| 125 }, |
| 126 }, |
| 127 false, |
| 128 }, |
| 129 { |
| 130 { |
| 131 L"Empty DisplayName", |
| 132 false, |
| 133 false, |
| 134 L"", |
| 135 kValidUninstallString, |
| 136 { |
| 137 kValidComponentPath, |
| 138 }, |
| 139 }, |
| 140 false, |
| 141 }, |
| 142 { |
| 143 { |
| 144 L"Empty UninstallString", |
| 145 false, |
| 146 false, |
| 147 kValidDisplayName, |
| 148 L"", |
| 149 { |
| 150 kValidComponentPath, |
| 151 }, |
| 152 }, |
| 153 false, |
| 154 }, |
| 155 { |
| 156 { |
| 157 L"IsSystemComponent", |
| 158 true, |
| 159 false, |
| 160 kValidDisplayName, |
| 161 kValidUninstallString, |
| 162 { |
| 163 kValidComponentPath, |
| 164 }, |
| 165 }, |
| 166 false, |
| 167 }, |
| 168 { |
| 169 { |
| 170 L"MicrosoftPublished", |
| 171 false, |
| 172 true, |
| 173 kValidDisplayName, |
| 174 kValidUninstallString, |
| 175 { |
| 176 kValidComponentPath, |
| 177 }, |
| 178 }, |
| 179 false, |
| 180 }, |
| 181 { |
| 182 { |
| 183 L"NoValidComponents", |
| 184 false, |
| 185 false, |
| 186 kValidDisplayName, |
| 187 kValidUninstallString, |
| 188 { |
| 189 L"02:\\registry\\path", L"c:\\not\\dll\\path.txt", |
| 190 }, |
| 191 }, |
| 192 false, |
| 193 }, |
| 194 { |
| 195 { |
| 196 L"ValidEntry", |
| 197 false, |
| 198 false, |
| 199 L"Name5", |
| 200 kValidUninstallString, |
| 201 { |
| 202 L"c:\\valid\\path\\test.dll", L"c:\\valid\\path\\another.dll", |
| 203 }, |
| 204 }, |
| 205 true, |
| 206 }, |
| 207 }; |
| 208 |
| 209 for (const auto& test_case : kTestCases) |
| 210 SetUpFakeMSIProgram(test_case.first); |
| 211 |
| 212 InstalledPrograms installed_programs; |
| 213 |
| 214 installed_programs.Initialize(base::Closure()); |
| 215 |
| 216 base::RunLoop().RunUntilIdle(); |
| 217 |
| 218 for (const auto& test_case : kTestCases) { |
| 219 for (const auto& path : test_case.first.components) { |
| 220 base::string16 display_name; |
| 221 EXPECT_EQ(test_case.second, installed_programs.GetInstalledProgramName( |
| 222 base::FilePath(path), &display_name)); |
| 223 if (test_case.second) { |
| 224 EXPECT_EQ(test_case.first.display_name, display_name); |
| 225 } |
| 226 } |
| 227 } |
| 228 } |
OLD | NEW |