Elevation.Tests.cpp
1 #include "pch.h" 2 #include "TestHelpers.h" 3 #include <elevation.h> 4 5 using namespace Microsoft::VisualStudio::CppUnitTestFramework; 6 7 namespace UnitTestsCommonUtils 8 { 9 TEST_CLASS(ElevationTests) 10 { 11 public: 12 // is_process_elevated tests 13 TEST_METHOD(IsProcessElevated_ReturnsBoolean) 14 { 15 bool result = is_process_elevated(false); 16 Assert::IsTrue(result == true || result == false); 17 } 18 19 TEST_METHOD(IsProcessElevated_CachedValue_ReturnsSameResult) 20 { 21 bool result1 = is_process_elevated(true); 22 bool result2 = is_process_elevated(true); 23 24 // Cached value should be consistent 25 Assert::AreEqual(result1, result2); 26 } 27 28 TEST_METHOD(IsProcessElevated_UncachedValue_ReturnsBoolean) 29 { 30 bool result = is_process_elevated(false); 31 Assert::IsTrue(result == true || result == false); 32 } 33 34 TEST_METHOD(IsProcessElevated_CachedAndUncached_AreConsistent) 35 { 36 // Both should return the same value for the same process 37 bool cached = is_process_elevated(true); 38 bool uncached = is_process_elevated(false); 39 40 Assert::AreEqual(cached, uncached); 41 } 42 43 // check_user_is_admin tests 44 TEST_METHOD(CheckUserIsAdmin_ReturnsBoolean) 45 { 46 bool result = check_user_is_admin(); 47 Assert::IsTrue(result == true || result == false); 48 } 49 50 TEST_METHOD(CheckUserIsAdmin_ConsistentResults) 51 { 52 bool result1 = check_user_is_admin(); 53 bool result2 = check_user_is_admin(); 54 bool result3 = check_user_is_admin(); 55 56 Assert::AreEqual(result1, result2); 57 Assert::AreEqual(result2, result3); 58 } 59 60 // Relationship between elevation and admin 61 TEST_METHOD(ElevationAndAdmin_Relationship) 62 { 63 bool elevated = is_process_elevated(false); 64 bool admin = check_user_is_admin(); 65 (void)admin; 66 67 // If elevated, user should typically be admin 68 // But user can be admin without process being elevated 69 if (elevated) 70 { 71 // Elevated process usually means admin user 72 // (though there are edge cases) 73 } 74 // Just verify both functions return without crashing 75 Assert::IsTrue(true); 76 } 77 78 // IsProcessOfWindowElevated tests 79 TEST_METHOD(IsProcessOfWindowElevated_DesktopWindow_ReturnsBoolean) 80 { 81 HWND desktop = GetDesktopWindow(); 82 if (desktop) 83 { 84 bool result = IsProcessOfWindowElevated(desktop); 85 Assert::IsTrue(result == true || result == false); 86 } 87 Assert::IsTrue(true); 88 } 89 90 TEST_METHOD(IsProcessOfWindowElevated_InvalidHwnd_DoesNotCrash) 91 { 92 bool result = IsProcessOfWindowElevated(nullptr); 93 // Should handle null HWND gracefully 94 Assert::IsTrue(result == true || result == false); 95 } 96 97 // ProcessInfo struct tests 98 TEST_METHOD(ProcessInfo_DefaultConstruction) 99 { 100 ProcessInfo info{}; 101 Assert::AreEqual(static_cast<DWORD>(0), info.processID); 102 } 103 104 // Thread safety tests 105 TEST_METHOD(IsProcessElevated_ThreadSafe) 106 { 107 std::vector<std::thread> threads; 108 std::atomic<int> successCount{ 0 }; 109 110 for (int i = 0; i < 10; ++i) 111 { 112 threads.emplace_back([&successCount]() { 113 for (int j = 0; j < 10; ++j) 114 { 115 is_process_elevated(j % 2 == 0); 116 successCount++; 117 } 118 }); 119 } 120 121 for (auto& t : threads) 122 { 123 t.join(); 124 } 125 126 Assert::AreEqual(100, successCount.load()); 127 } 128 129 // Performance of cached value 130 TEST_METHOD(IsProcessElevated_CachedPerformance) 131 { 132 auto start = std::chrono::high_resolution_clock::now(); 133 134 for (int i = 0; i < 10000; ++i) 135 { 136 is_process_elevated(true); 137 } 138 139 auto end = std::chrono::high_resolution_clock::now(); 140 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); 141 142 // Cached calls should be very fast 143 Assert::IsTrue(duration.count() < 1000); 144 } 145 }; 146 }