Home | History | Annotate | Download | only in win
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/win/shortcut.h"
      6 
      7 #include <string>
      8 
      9 #include "base/file_util.h"
     10 #include "base/files/file_path.h"
     11 #include "base/files/scoped_temp_dir.h"
     12 #include "base/test/test_file_util.h"
     13 #include "base/test/test_shortcut_win.h"
     14 #include "base/win/scoped_com_initializer.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace base {
     18 namespace win {
     19 
     20 namespace {
     21 
     22 static const char kFileContents[] = "This is a target.";
     23 static const char kFileContents2[] = "This is another target.";
     24 
     25 class ShortcutTest : public testing::Test {
     26  protected:
     27   virtual void SetUp() OVERRIDE {
     28     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     29     ASSERT_TRUE(temp_dir_2_.CreateUniqueTempDir());
     30 
     31     link_file_ = temp_dir_.path().Append(L"My Link.lnk");
     32 
     33     // Shortcut 1's properties
     34     {
     35       const FilePath target_file(temp_dir_.path().Append(L"Target 1.txt"));
     36       file_util::WriteFile(target_file, kFileContents,
     37                            arraysize(kFileContents));
     38 
     39       link_properties_.set_target(target_file);
     40       link_properties_.set_working_dir(temp_dir_.path());
     41       link_properties_.set_arguments(L"--magic --awesome");
     42       link_properties_.set_description(L"Chrome is awesome.");
     43       link_properties_.set_icon(link_properties_.target, 4);
     44       link_properties_.set_app_id(L"Chrome");
     45       link_properties_.set_dual_mode(false);
     46     }
     47 
     48     // Shortcut 2's properties (all different from properties of shortcut 1).
     49     {
     50       const FilePath target_file_2(temp_dir_.path().Append(L"Target 2.txt"));
     51       file_util::WriteFile(target_file_2, kFileContents2,
     52                            arraysize(kFileContents2));
     53 
     54       FilePath icon_path_2;
     55       base::CreateTemporaryFileInDir(temp_dir_.path(), &icon_path_2);
     56 
     57       link_properties_2_.set_target(target_file_2);
     58       link_properties_2_.set_working_dir(temp_dir_2_.path());
     59       link_properties_2_.set_arguments(L"--super --crazy");
     60       link_properties_2_.set_description(L"The best in the west.");
     61       link_properties_2_.set_icon(icon_path_2, 0);
     62       link_properties_2_.set_app_id(L"Chrome.UserLevelCrazySuffix");
     63       link_properties_2_.set_dual_mode(true);
     64     }
     65   }
     66 
     67   ScopedCOMInitializer com_initializer_;
     68   ScopedTempDir temp_dir_;
     69   ScopedTempDir temp_dir_2_;
     70 
     71   // The link file to be created/updated in the shortcut tests below.
     72   FilePath link_file_;
     73 
     74   // Properties for the created shortcut.
     75   ShortcutProperties link_properties_;
     76 
     77   // Properties for the updated shortcut.
     78   ShortcutProperties link_properties_2_;
     79 };
     80 
     81 }  // namespace
     82 
     83 TEST_F(ShortcutTest, CreateAndResolveShortcut) {
     84   ShortcutProperties only_target_properties;
     85   only_target_properties.set_target(link_properties_.target);
     86 
     87   ASSERT_TRUE(CreateOrUpdateShortcutLink(
     88       link_file_, only_target_properties, SHORTCUT_CREATE_ALWAYS));
     89 
     90   FilePath resolved_name;
     91   EXPECT_TRUE(ResolveShortcut(link_file_, &resolved_name, NULL));
     92 
     93   char read_contents[arraysize(kFileContents)];
     94   base::ReadFile(resolved_name, read_contents, arraysize(read_contents));
     95   EXPECT_STREQ(kFileContents, read_contents);
     96 }
     97 
     98 TEST_F(ShortcutTest, ResolveShortcutWithArgs) {
     99   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    100       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
    101 
    102   FilePath resolved_name;
    103   string16 args;
    104   EXPECT_TRUE(ResolveShortcut(link_file_, &resolved_name, &args));
    105 
    106   char read_contents[arraysize(kFileContents)];
    107   base::ReadFile(resolved_name, read_contents, arraysize(read_contents));
    108   EXPECT_STREQ(kFileContents, read_contents);
    109   EXPECT_EQ(link_properties_.arguments, args);
    110 }
    111 
    112 TEST_F(ShortcutTest, CreateShortcutWithOnlySomeProperties) {
    113   ShortcutProperties target_and_args_properties;
    114   target_and_args_properties.set_target(link_properties_.target);
    115   target_and_args_properties.set_arguments(link_properties_.arguments);
    116 
    117   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    118       link_file_, target_and_args_properties,
    119       SHORTCUT_CREATE_ALWAYS));
    120 
    121   ValidateShortcut(link_file_, target_and_args_properties);
    122 }
    123 
    124 TEST_F(ShortcutTest, CreateShortcutVerifyProperties) {
    125   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    126       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
    127 
    128   ValidateShortcut(link_file_, link_properties_);
    129 }
    130 
    131 TEST_F(ShortcutTest, UpdateShortcutVerifyProperties) {
    132   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    133       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
    134 
    135   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    136       link_file_, link_properties_2_, SHORTCUT_UPDATE_EXISTING));
    137 
    138   ValidateShortcut(link_file_, link_properties_2_);
    139 }
    140 
    141 TEST_F(ShortcutTest, UpdateShortcutUpdateOnlyTargetAndResolve) {
    142   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    143       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
    144 
    145   ShortcutProperties update_only_target_properties;
    146   update_only_target_properties.set_target(link_properties_2_.target);
    147 
    148   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    149       link_file_, update_only_target_properties,
    150       SHORTCUT_UPDATE_EXISTING));
    151 
    152   ShortcutProperties expected_properties = link_properties_;
    153   expected_properties.set_target(link_properties_2_.target);
    154   ValidateShortcut(link_file_, expected_properties);
    155 
    156   FilePath resolved_name;
    157   EXPECT_TRUE(ResolveShortcut(link_file_, &resolved_name, NULL));
    158 
    159   char read_contents[arraysize(kFileContents2)];
    160   base::ReadFile(resolved_name, read_contents, arraysize(read_contents));
    161   EXPECT_STREQ(kFileContents2, read_contents);
    162 }
    163 
    164 TEST_F(ShortcutTest, UpdateShortcutMakeDualMode) {
    165   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    166       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
    167 
    168   ShortcutProperties make_dual_mode_properties;
    169   make_dual_mode_properties.set_dual_mode(true);
    170 
    171   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    172       link_file_, make_dual_mode_properties,
    173       SHORTCUT_UPDATE_EXISTING));
    174 
    175   ShortcutProperties expected_properties = link_properties_;
    176   expected_properties.set_dual_mode(true);
    177   ValidateShortcut(link_file_, expected_properties);
    178 }
    179 
    180 TEST_F(ShortcutTest, UpdateShortcutRemoveDualMode) {
    181   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    182       link_file_, link_properties_2_, SHORTCUT_CREATE_ALWAYS));
    183 
    184   ShortcutProperties remove_dual_mode_properties;
    185   remove_dual_mode_properties.set_dual_mode(false);
    186 
    187   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    188       link_file_, remove_dual_mode_properties,
    189       SHORTCUT_UPDATE_EXISTING));
    190 
    191   ShortcutProperties expected_properties = link_properties_2_;
    192   expected_properties.set_dual_mode(false);
    193   ValidateShortcut(link_file_, expected_properties);
    194 }
    195 
    196 TEST_F(ShortcutTest, UpdateShortcutClearArguments) {
    197   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    198       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
    199 
    200   ShortcutProperties clear_arguments_properties;
    201   clear_arguments_properties.set_arguments(string16());
    202 
    203   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    204       link_file_, clear_arguments_properties,
    205       SHORTCUT_UPDATE_EXISTING));
    206 
    207   ShortcutProperties expected_properties = link_properties_;
    208   expected_properties.set_arguments(string16());
    209   ValidateShortcut(link_file_, expected_properties);
    210 }
    211 
    212 TEST_F(ShortcutTest, FailUpdateShortcutThatDoesNotExist) {
    213   ASSERT_FALSE(CreateOrUpdateShortcutLink(
    214       link_file_, link_properties_, SHORTCUT_UPDATE_EXISTING));
    215   ASSERT_FALSE(PathExists(link_file_));
    216 }
    217 
    218 TEST_F(ShortcutTest, ReplaceShortcutAllProperties) {
    219   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    220       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
    221 
    222   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    223       link_file_, link_properties_2_, SHORTCUT_REPLACE_EXISTING));
    224 
    225   ValidateShortcut(link_file_, link_properties_2_);
    226 }
    227 
    228 TEST_F(ShortcutTest, ReplaceShortcutSomeProperties) {
    229   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    230       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
    231 
    232   ShortcutProperties new_properties;
    233   new_properties.set_target(link_properties_2_.target);
    234   new_properties.set_arguments(link_properties_2_.arguments);
    235   new_properties.set_description(link_properties_2_.description);
    236   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    237       link_file_, new_properties, SHORTCUT_REPLACE_EXISTING));
    238 
    239   // Expect only properties in |new_properties| to be set, all other properties
    240   // should have been overwritten.
    241   ShortcutProperties expected_properties(new_properties);
    242   expected_properties.set_working_dir(FilePath());
    243   expected_properties.set_icon(FilePath(), 0);
    244   expected_properties.set_app_id(string16());
    245   expected_properties.set_dual_mode(false);
    246   ValidateShortcut(link_file_, expected_properties);
    247 }
    248 
    249 TEST_F(ShortcutTest, FailReplaceShortcutThatDoesNotExist) {
    250   ASSERT_FALSE(CreateOrUpdateShortcutLink(
    251       link_file_, link_properties_, SHORTCUT_REPLACE_EXISTING));
    252   ASSERT_FALSE(PathExists(link_file_));
    253 }
    254 
    255 // Test that the old arguments remain on the replaced shortcut when not
    256 // otherwise specified.
    257 TEST_F(ShortcutTest, ReplaceShortcutKeepOldArguments) {
    258   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    259       link_file_, link_properties_, SHORTCUT_CREATE_ALWAYS));
    260 
    261   // Do not explicitly set the arguments.
    262   link_properties_2_.options &=
    263       ~ShortcutProperties::PROPERTIES_ARGUMENTS;
    264   ASSERT_TRUE(CreateOrUpdateShortcutLink(
    265       link_file_, link_properties_2_, SHORTCUT_REPLACE_EXISTING));
    266 
    267   ShortcutProperties expected_properties(link_properties_2_);
    268   expected_properties.set_arguments(link_properties_.arguments);
    269   ValidateShortcut(link_file_, expected_properties);
    270 }
    271 
    272 }  // namespace win
    273 }  // namespace base
    274