/ src / common / UnitTests-CommonUtils / Package.Tests.cpp
Package.Tests.cpp
  1  #include "pch.h"
  2  #include "TestHelpers.h"
  3  #include <package.h>
  4  
  5  using namespace Microsoft::VisualStudio::CppUnitTestFramework;
  6  using namespace package;
  7  
  8  namespace UnitTestsCommonUtils
  9  {
 10      TEST_CLASS(PackageTests)
 11      {
 12      public:
 13          // IsWin11OrGreater tests
 14          TEST_METHOD(IsWin11OrGreater_ReturnsBoolean)
 15          {
 16              bool result = IsWin11OrGreater();
 17              Assert::IsTrue(result == true || result == false);
 18          }
 19  
 20          TEST_METHOD(IsWin11OrGreater_ConsistentResults)
 21          {
 22              bool result1 = IsWin11OrGreater();
 23              bool result2 = IsWin11OrGreater();
 24              bool result3 = IsWin11OrGreater();
 25  
 26              Assert::AreEqual(result1, result2);
 27              Assert::AreEqual(result2, result3);
 28          }
 29  
 30          // PACKAGE_VERSION struct tests
 31          TEST_METHOD(PackageVersion_DefaultConstruction)
 32          {
 33              PACKAGE_VERSION version{};
 34              Assert::AreEqual(static_cast<UINT16>(0), version.Major);
 35              Assert::AreEqual(static_cast<UINT16>(0), version.Minor);
 36              Assert::AreEqual(static_cast<UINT16>(0), version.Build);
 37              Assert::AreEqual(static_cast<UINT16>(0), version.Revision);
 38          }
 39  
 40          TEST_METHOD(PackageVersion_Assignment)
 41          {
 42              PACKAGE_VERSION version{};
 43              version.Major = 1;
 44              version.Minor = 2;
 45              version.Build = 3;
 46              version.Revision = 4;
 47  
 48              Assert::AreEqual(static_cast<UINT16>(1), version.Major);
 49              Assert::AreEqual(static_cast<UINT16>(2), version.Minor);
 50              Assert::AreEqual(static_cast<UINT16>(3), version.Build);
 51              Assert::AreEqual(static_cast<UINT16>(4), version.Revision);
 52          }
 53  
 54          // ComInitializer tests
 55          TEST_METHOD(ComInitializer_InitializesAndUninitializesCom)
 56          {
 57              {
 58                  ComInitializer comInit;
 59                  // COM should be initialized within this scope
 60              }
 61              // COM should be uninitialized after scope
 62  
 63              // Verify we can initialize again
 64              {
 65                  ComInitializer comInit2;
 66              }
 67  
 68              Assert::IsTrue(true);
 69          }
 70  
 71          TEST_METHOD(ComInitializer_MultipleInstances)
 72          {
 73              ComInitializer init1;
 74              ComInitializer init2;
 75              ComInitializer init3;
 76  
 77              // Multiple initializations should work (COM uses reference counting)
 78              Assert::IsTrue(true);
 79          }
 80  
 81          // GetRegisteredPackage tests
 82          TEST_METHOD(GetRegisteredPackage_NonExistentPackage_ReturnsEmpty)
 83          {
 84              auto result = GetRegisteredPackage(L"NonExistentPackage12345", false);
 85  
 86              // Should return empty for non-existent package
 87              Assert::IsFalse(result.has_value());
 88          }
 89  
 90          TEST_METHOD(GetRegisteredPackage_EmptyName_DoesNotCrash)
 91          {
 92              auto result = GetRegisteredPackage(L"", false);
 93              // Behavior may vary based on package enumeration; just ensure it doesn't crash.
 94              Assert::IsTrue(true);
 95          }
 96  
 97          // IsPackageRegisteredWithPowerToysVersion tests
 98          TEST_METHOD(IsPackageRegisteredWithPowerToysVersion_NonExistentPackage_ReturnsFalse)
 99          {
100              bool result = IsPackageRegisteredWithPowerToysVersion(L"NonExistentPackage12345");
101              Assert::IsFalse(result);
102          }
103  
104          TEST_METHOD(IsPackageRegisteredWithPowerToysVersion_EmptyName_ReturnsFalse)
105          {
106              bool result = IsPackageRegisteredWithPowerToysVersion(L"");
107              Assert::IsFalse(result);
108          }
109  
110          // FindMsixFile tests
111          TEST_METHOD(FindMsixFile_NonExistentDirectory_ReturnsEmpty)
112          {
113              auto result = FindMsixFile(L"C:\\NonExistentDirectory12345", false);
114              Assert::IsTrue(result.empty());
115          }
116  
117          TEST_METHOD(FindMsixFile_SystemDirectory_DoesNotCrash)
118          {
119              // System32 probably doesn't have MSIX files, but shouldn't crash
120              auto result = FindMsixFile(L"C:\\Windows\\System32", false);
121              // May or may not find files, but should not crash
122              Assert::IsTrue(true);
123          }
124  
125          TEST_METHOD(FindMsixFile_RecursiveSearch_DoesNotCrash)
126          {
127              // Use temp directory which should exist
128              wchar_t tempPath[MAX_PATH];
129              GetTempPathW(MAX_PATH, tempPath);
130  
131              auto result = FindMsixFile(tempPath, true);
132              // May or may not find files, but should not crash
133              Assert::IsTrue(true);
134          }
135  
136          // GetPackageNameAndVersionFromAppx tests
137          TEST_METHOD(GetPackageNameAndVersionFromAppx_NonExistentFile_ReturnsFalse)
138          {
139              std::wstring name;
140              PACKAGE_VERSION version{};
141  
142              bool result = GetPackageNameAndVersionFromAppx(L"C:\\NonExistent\\file.msix", name, version);
143              Assert::IsFalse(result);
144          }
145  
146          TEST_METHOD(GetPackageNameAndVersionFromAppx_EmptyPath_ReturnsFalse)
147          {
148              std::wstring name;
149              PACKAGE_VERSION version{};
150  
151              bool result = GetPackageNameAndVersionFromAppx(L"", name, version);
152              Assert::IsFalse(result);
153          }
154  
155          // Thread safety
156          TEST_METHOD(IsWin11OrGreater_ThreadSafe)
157          {
158              std::vector<std::thread> threads;
159              std::atomic<int> successCount{ 0 };
160  
161              for (int i = 0; i < 10; ++i)
162              {
163                  threads.emplace_back([&successCount]() {
164                      for (int j = 0; j < 10; ++j)
165                      {
166                          IsWin11OrGreater();
167                          successCount++;
168                      }
169                  });
170              }
171  
172              for (auto& t : threads)
173              {
174                  t.join();
175              }
176  
177              Assert::AreEqual(100, successCount.load());
178          }
179      };
180  }