/** * @file tests/unit/test_process.cpp * @brief Test src/process.* functions. */ // test imports #include "../tests_common.h" // standard imports #include #include // local imports #include namespace fs = std::filesystem; class ProcessPNGTest: public ::testing::Test { protected: void SetUp() override { // Create test directory test_dir = fs::temp_directory_path() / "sunshine_process_png_test"; fs::create_directories(test_dir); } void TearDown() override { // Clean up test directory if (fs::exists(test_dir)) { fs::remove_all(test_dir); } } // Helper function to create a file with specific content void createTestFile(const fs::path &path, const std::vector &content) const { std::ofstream file(path, std::ios::binary); file.write(reinterpret_cast(content.data()), content.size()); file.close(); } fs::path test_dir; }; // Tests for check_valid_png function TEST_F(ProcessPNGTest, CheckValidPNG_ValidSignature) { // Valid PNG signature const std::vector valid_png_data = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, // PNG signature // Add some dummy data to make it more realistic 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52 }; const fs::path test_file = test_dir / "valid.png"; createTestFile(test_file, valid_png_data); EXPECT_TRUE(proc::check_valid_png(test_file)); } TEST_F(ProcessPNGTest, CheckValidPNG_WrongSignature) { // Invalid PNG signature (wrong magic bytes) const std::vector invalid_png_data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const fs::path test_file = test_dir / "invalid.png"; createTestFile(test_file, invalid_png_data); EXPECT_FALSE(proc::check_valid_png(test_file)); } TEST_F(ProcessPNGTest, CheckValidPNG_TooShort) { // File too short (less than 8 bytes) const std::vector short_data = { 0x89, 0x50, 0x4E, 0x47 }; const fs::path test_file = test_dir / "short.png"; createTestFile(test_file, short_data); EXPECT_FALSE(proc::check_valid_png(test_file)); } TEST_F(ProcessPNGTest, CheckValidPNG_EmptyFile) { // Empty file const std::vector empty_data = {}; const fs::path test_file = test_dir / "empty.png"; createTestFile(test_file, empty_data); EXPECT_FALSE(proc::check_valid_png(test_file)); } TEST_F(ProcessPNGTest, CheckValidPNG_NonExistentFile) { // File doesn't exist const fs::path test_file = test_dir / "nonexistent.png"; EXPECT_FALSE(proc::check_valid_png(test_file)); } TEST_F(ProcessPNGTest, CheckValidPNG_RealFile) { // Test with the actual sunshine.png from the project root // Only run this test if the file exists if (const fs::path sunshine_png = fs::path(SUNSHINE_SOURCE_DIR) / "sunshine.png"; fs::exists(sunshine_png)) { EXPECT_TRUE(proc::check_valid_png(sunshine_png)); } else { GTEST_SKIP() << "sunshine.png not found in project root"; } } TEST_F(ProcessPNGTest, CheckValidPNG_JPEGFile) { // JPEG signature (not PNG) const std::vector jpeg_data = { 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46 }; const fs::path test_file = test_dir / "fake.png"; createTestFile(test_file, jpeg_data); EXPECT_FALSE(proc::check_valid_png(test_file)); } TEST_F(ProcessPNGTest, CheckValidPNG_PartialSignature) { // Partial PNG signature (first 4 bytes correct, rest wrong) const std::vector partial_png_data = { 0x89, 0x50, 0x4E, 0x47, 0x00, 0x00, 0x00, 0x00 }; const fs::path test_file = test_dir / "partial.png"; createTestFile(test_file, partial_png_data); EXPECT_FALSE(proc::check_valid_png(test_file)); } // Tests for validate_app_image_path function TEST_F(ProcessPNGTest, ValidateAppImagePath_EmptyPath) { // Empty path should return default const std::string result = proc::validate_app_image_path(""); EXPECT_EQ(result, DEFAULT_APP_IMAGE_PATH); } TEST_F(ProcessPNGTest, ValidateAppImagePath_NonPNGExtension) { // Non-PNG extension should return default const std::string result = proc::validate_app_image_path("image.jpg"); EXPECT_EQ(result, DEFAULT_APP_IMAGE_PATH); } TEST_F(ProcessPNGTest, ValidateAppImagePath_CaseInsensitiveExtension) { // Test that .PNG (uppercase) is recognized // Create a valid PNG file const std::vector valid_png_data = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52 }; const fs::path test_file = test_dir / "test.PNG"; createTestFile(test_file, valid_png_data); const std::string result = proc::validate_app_image_path(test_file.string()); // Should accept uppercase .PNG extension EXPECT_NE(result, DEFAULT_APP_IMAGE_PATH); } TEST_F(ProcessPNGTest, ValidateAppImagePath_NonExistentFile) { // Non-existent PNG file should return default const std::string result = proc::validate_app_image_path("/nonexistent/path/image.png"); EXPECT_EQ(result, DEFAULT_APP_IMAGE_PATH); } TEST_F(ProcessPNGTest, ValidateAppImagePath_InvalidPNGSignature) { // File with .png extension but invalid signature should return default const std::vector invalid_data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const fs::path test_file = test_dir / "invalid.png"; createTestFile(test_file, invalid_data); const std::string result = proc::validate_app_image_path(test_file.string()); EXPECT_EQ(result, DEFAULT_APP_IMAGE_PATH); } TEST_F(ProcessPNGTest, ValidateAppImagePath_ValidPNG) { // Valid PNG file should return the path const std::vector valid_png_data = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52 }; const fs::path test_file = test_dir / "valid.png"; createTestFile(test_file, valid_png_data); const std::string result = proc::validate_app_image_path(test_file.string()); EXPECT_EQ(result, test_file.string()); } TEST_F(ProcessPNGTest, ValidateAppImagePath_OldSteamDefault) { // Test the special case for old steam image path const std::string result = proc::validate_app_image_path("./assets/steam.png"); EXPECT_EQ(result, SUNSHINE_ASSETS_DIR "/steam.png"); }