import std/[unittest, os, tempfiles, options, strutils] import nip/nip_installer import nip/manifest_parser import nip/cas suite "NIP Advanced Desktop Integration Tests": setup: let tempDir = createTempDir("nip_test_desktop_", "") let casRoot = tempDir / "cas" let mockHome = tempDir / "home" createDir(mockHome / ".local/share/nexus/nips") createDir(mockHome / ".local/share/applications") createDir(mockHome / ".local/share/icons/hicolor/48x48/apps") createDir(casRoot) discard initCasManager(casRoot, casRoot) var ni = NipInstaller( casRoot: casRoot, installRoot: mockHome / ".local/share/nexus/nips", appsRoot: mockHome / ".local/share/applications", iconsRoot: mockHome / ".local/share/icons", dryRun: false # We want to test file creation ) teardown: removeDir(tempDir) test "Install NIP with Icon and StartupWMClass": # 1. Prepare CAS (Icon file) let iconContent = "fake png content" let casObj = storeObject(iconContent, ni.casRoot) # 2. Create Manifest var manifest = PackageManifest( name: "icon-app", version: parseSemanticVersion("1.0.0"), license: "MIT", artifactHash: "hash123" ) manifest.files.add(FileSpec( path: "icon.png", hash: string(casObj.hash), size: iconContent.len, permissions: "644" )) manifest.desktop = some(DesktopIntegration( displayName: "Icon App", icon: some("icon.png"), startupWMClass: some("IconAppWindow") )) # 3. Install # Note: update-desktop-database will fail in test env if not in PATH or no permissions # But execCmd returns exit code, we discard it in code. # Ideally we should mock execCmd, but for integration test we just check files. ni.installNip(manifest) # 4. Verify Icon Installation let iconDest = ni.iconsRoot / "hicolor/48x48/apps/icon-app.png" check fileExists(iconDest) check readFile(iconDest) == iconContent # 5. Verify StartupWMClass in .desktop let desktopFile = ni.appsRoot / "icon-app.desktop" check fileExists(desktopFile) let content = readFile(desktopFile) check content.contains("StartupWMClass=IconAppWindow") # 6. Remove ni.removeNip(manifest) # 7. Verify Removal check not fileExists(iconDest) check not fileExists(desktopFile) test "Install NIP with System Icon (No File Copy)": var manifest = PackageManifest( name: "sys-icon-app", version: parseSemanticVersion("1.0.0"), license: "MIT", artifactHash: "hash456" ) manifest.desktop = some(DesktopIntegration( displayName: "Sys Icon App", icon: some("firefox") # System icon name )) ni.installNip(manifest) # Verify NO icon file copied (since "firefox" doesn't end in .png/.svg) let iconDest = ni.iconsRoot / "hicolor/48x48/apps/sys-icon-app.png" check not fileExists(iconDest) # Verify .desktop has Icon=firefox let desktopFile = ni.appsRoot / "sys-icon-app.desktop" check readFile(desktopFile).contains("Icon=firefox")