mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46:05 +01:00
Merge 415153929c into 0562fef070
This commit is contained in:
commit
2f3efbdef6
10 changed files with 599 additions and 0 deletions
11
modules/misc/news/2025/10/2025-10-01_06-44-15.nix
Normal file
11
modules/misc/news/2025/10/2025-10-01_06-44-15.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
time = "2025-10-01T12:44:15+00:00";
|
||||||
|
condition = true;
|
||||||
|
message = ''
|
||||||
|
A new module is available: 'programs.webApps'.
|
||||||
|
|
||||||
|
This module enables declarative configuration of web applications as
|
||||||
|
desktop entries, supporting Chromium-based browsers, Firefox, and
|
||||||
|
automatic browser detection with proper app mode integration.
|
||||||
|
'';
|
||||||
|
}
|
||||||
212
modules/programs/webapps.nix
Normal file
212
modules/programs/webapps.nix
Normal file
|
|
@ -0,0 +1,212 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.programs.webApps;
|
||||||
|
|
||||||
|
# Type for a single web app
|
||||||
|
webAppOpts = types.submodule ({
|
||||||
|
options = {
|
||||||
|
url = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "URL of the web application to launch.";
|
||||||
|
example = "https://github.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Name of the web application. If not provided, will be derived from the attribute name.";
|
||||||
|
example = "GitHub";
|
||||||
|
};
|
||||||
|
|
||||||
|
icon = mkOption {
|
||||||
|
type = types.nullOr (types.either types.str types.path);
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Icon for the web application.
|
||||||
|
Can be a path to an icon file or a name of an icon from the current theme.
|
||||||
|
|
||||||
|
For best results, use declarative icon packages like:
|
||||||
|
- `"$${pkgs.papirus-icon-theme}/share/icons/Papirus/64x64/apps/Gmail-mail.google.com.svg"`
|
||||||
|
- Theme icon names like `"mail-client"` (requires icon theme in `home.packages`)
|
||||||
|
|
||||||
|
Popular icon themes: papirus-icon-theme, adwaita-icon-theme, arc-icon-theme
|
||||||
|
'';
|
||||||
|
example = literalExpression ''
|
||||||
|
"$${pkgs.papirus-icon-theme}/share/icons/Papirus/64x64/apps/Gmail-mail.google.com.svg"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
categories = mkOption {
|
||||||
|
type = with types; nullOr (listOf str);
|
||||||
|
default = [
|
||||||
|
"Network"
|
||||||
|
"WebBrowser"
|
||||||
|
];
|
||||||
|
description = "Categories in which the entry should be shown in application menus.";
|
||||||
|
example = ''[ "Development" "Network" ]'';
|
||||||
|
};
|
||||||
|
|
||||||
|
mimeTypes = mkOption {
|
||||||
|
type = with types; nullOr (listOf str);
|
||||||
|
default = null;
|
||||||
|
description = "The MIME types supported by this application.";
|
||||||
|
example = ''[ "x-scheme-handler/mailto" ]'';
|
||||||
|
};
|
||||||
|
|
||||||
|
startupWmClass = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "The StartupWMClass to use in the .desktop file.";
|
||||||
|
example = "github.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraOptions = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
default = { };
|
||||||
|
description = "Extra options to pass to the browser when launching the webapp.";
|
||||||
|
example = ''{ profile-directory = "Profile 3"; }'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
# Get browser command based on package
|
||||||
|
getBrowserCommand =
|
||||||
|
browserPkg: url: extraOptions:
|
||||||
|
let
|
||||||
|
# Desktop entries don't need shell escaping, just basic space escaping
|
||||||
|
escapeDesktopArg = arg: builtins.replaceStrings [ " " ] [ "\\ " ] (toString arg);
|
||||||
|
|
||||||
|
optionString = concatStringsSep " " (
|
||||||
|
mapAttrsToList (name: value: "--${name}=${escapeDesktopArg value}") extraOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
# Detect browser type from package name
|
||||||
|
browserName = browserPkg.pname or (builtins.parseDrvName browserPkg.name).name;
|
||||||
|
|
||||||
|
isChromiumBased = elem browserName [
|
||||||
|
"chromium"
|
||||||
|
"brave"
|
||||||
|
"google-chrome"
|
||||||
|
"google-chrome-stable"
|
||||||
|
"vivaldi"
|
||||||
|
];
|
||||||
|
|
||||||
|
binary = "${toString browserPkg}/bin/${browserName}";
|
||||||
|
in
|
||||||
|
if isChromiumBased then
|
||||||
|
"${binary} --app=${escapeDesktopArg url} ${optionString}"
|
||||||
|
else if browserName == "firefox" then
|
||||||
|
"${binary} ${escapeDesktopArg url}" # Firefox doesn't support --app mode
|
||||||
|
else
|
||||||
|
# Fallback: assume chromium-based behavior
|
||||||
|
"${binary} --app=${escapeDesktopArg url} ${optionString}";
|
||||||
|
|
||||||
|
# Auto-detect browser if not explicitly set
|
||||||
|
detectedBrowser =
|
||||||
|
if cfg.browser != null then
|
||||||
|
cfg.browser
|
||||||
|
else if config.programs.chromium.enable && config.programs.chromium.package != null then
|
||||||
|
config.programs.chromium.package
|
||||||
|
else if config.programs.brave.enable && config.programs.brave.package != null then
|
||||||
|
config.programs.brave.package
|
||||||
|
else if config.programs.firefox.enable && config.programs.firefox.package != null then
|
||||||
|
config.programs.firefox.package
|
||||||
|
else
|
||||||
|
pkgs.chromium; # Default fallback
|
||||||
|
|
||||||
|
# Create a desktop entry for a webapp
|
||||||
|
makeWebAppDesktopEntry =
|
||||||
|
name: appCfg:
|
||||||
|
let
|
||||||
|
# Derive app name if not explicitly set
|
||||||
|
appName = if appCfg.name != null then appCfg.name else name;
|
||||||
|
|
||||||
|
# Get the browser package
|
||||||
|
browserPkg = detectedBrowser;
|
||||||
|
|
||||||
|
# Create the launch command
|
||||||
|
launchCommand = getBrowserCommand browserPkg appCfg.url appCfg.extraOptions;
|
||||||
|
|
||||||
|
# Get browser name for StartupWMClass
|
||||||
|
browserName = browserPkg.pname or (builtins.parseDrvName browserPkg.name).name;
|
||||||
|
|
||||||
|
# Prepare StartupWMClass
|
||||||
|
startupWmClass =
|
||||||
|
if appCfg.startupWmClass != null then appCfg.startupWmClass else "${browserName}-webapp-${name}";
|
||||||
|
in
|
||||||
|
nameValuePair "webapp-${name}" {
|
||||||
|
name = appName;
|
||||||
|
genericName = "${appName} Web App";
|
||||||
|
exec = launchCommand;
|
||||||
|
icon = appCfg.icon;
|
||||||
|
terminal = false;
|
||||||
|
type = "Application";
|
||||||
|
categories = appCfg.categories;
|
||||||
|
mimeType = appCfg.mimeTypes;
|
||||||
|
settings = {
|
||||||
|
StartupWMClass = startupWmClass;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
meta.maintainers = with lib.maintainers; [ realsnick ];
|
||||||
|
|
||||||
|
options.programs.webApps = {
|
||||||
|
enable = mkEnableOption "web applications";
|
||||||
|
|
||||||
|
browser = mkOption {
|
||||||
|
type = types.nullOr types.package;
|
||||||
|
default = null;
|
||||||
|
example = literalExpression "pkgs.chromium";
|
||||||
|
description = ''
|
||||||
|
Browser package to use for launching web applications.
|
||||||
|
If null, will try to auto-detect from enabled browser programs.
|
||||||
|
Chromium-based browsers (chromium, brave, google-chrome) work best with --app mode.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
apps = mkOption {
|
||||||
|
type = types.attrsOf webAppOpts;
|
||||||
|
default = { };
|
||||||
|
description = "Set of web applications to install.";
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
github = {
|
||||||
|
url = "https://github.com";
|
||||||
|
icon = "github";
|
||||||
|
categories = [ "Development" "Network" ];
|
||||||
|
};
|
||||||
|
gmail = {
|
||||||
|
url = "https://mail.google.com";
|
||||||
|
name = "Gmail";
|
||||||
|
icon = ./icons/gmail.png;
|
||||||
|
mimeTypes = [ "x-scheme-handler/mailto" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.browser == null || lib.isDerivation cfg.browser;
|
||||||
|
message = ''
|
||||||
|
programs.webApps: browser must be a package derivation or null for auto-detection.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
# Create desktop entries for each web app
|
||||||
|
xdg.desktopEntries = mapAttrs' makeWebAppDesktopEntry cfg.apps;
|
||||||
|
};
|
||||||
|
}
|
||||||
27
tests/flake.lock
generated
Normal file
27
tests/flake.lock
generated
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1759036355,
|
||||||
|
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
36
tests/modules/programs/webapps/auto-detect.nix
Normal file
36
tests/modules/programs/webapps/auto-detect.nix
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
# Enable brave browser program to test auto-detection
|
||||||
|
programs.brave = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.brave;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.webApps = {
|
||||||
|
enable = true;
|
||||||
|
# browser = null; (let it auto-detect from brave)
|
||||||
|
|
||||||
|
apps = {
|
||||||
|
discord = {
|
||||||
|
url = "https://discord.com/channels/@me";
|
||||||
|
name = "Discord";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
# Check that the desktop entry was created
|
||||||
|
assertFileExists home-path/share/applications/webapp-discord.desktop
|
||||||
|
|
||||||
|
# Check that it detected brave and used --app mode
|
||||||
|
assertFileRegex home-path/share/applications/webapp-discord.desktop \
|
||||||
|
'Exec=.*brave.*--app=https://discord.com/channels/@me'
|
||||||
|
|
||||||
|
# Check StartupWMClass uses brave
|
||||||
|
assertFileRegex home-path/share/applications/webapp-discord.desktop \
|
||||||
|
'StartupWMClass=brave-webapp-discord'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
43
tests/modules/programs/webapps/basic.nix
Normal file
43
tests/modules/programs/webapps/basic.nix
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
programs.webApps = {
|
||||||
|
enable = true;
|
||||||
|
browser = pkgs.chromium;
|
||||||
|
|
||||||
|
apps = {
|
||||||
|
github = {
|
||||||
|
url = "https://github.com";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
# Check that the desktop entry was created
|
||||||
|
assertFileExists home-path/share/applications/webapp-github.desktop
|
||||||
|
|
||||||
|
# Check basic desktop entry content
|
||||||
|
assertFileRegex home-path/share/applications/webapp-github.desktop \
|
||||||
|
'Name=github'
|
||||||
|
assertFileRegex home-path/share/applications/webapp-github.desktop \
|
||||||
|
'GenericName=github Web App'
|
||||||
|
assertFileRegex home-path/share/applications/webapp-github.desktop \
|
||||||
|
'Type=Application'
|
||||||
|
assertFileRegex home-path/share/applications/webapp-github.desktop \
|
||||||
|
'Terminal=false'
|
||||||
|
|
||||||
|
# Check the exec command contains chromium with --app
|
||||||
|
assertFileRegex home-path/share/applications/webapp-github.desktop \
|
||||||
|
'Exec=.*chromium.*--app=https://github.com'
|
||||||
|
|
||||||
|
# Check categories
|
||||||
|
assertFileRegex home-path/share/applications/webapp-github.desktop \
|
||||||
|
'Categories=Network;WebBrowser'
|
||||||
|
|
||||||
|
# Check StartupWMClass
|
||||||
|
assertFileRegex home-path/share/applications/webapp-github.desktop \
|
||||||
|
'StartupWMClass=chromium-webapp-github'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
67
tests/modules/programs/webapps/custom-options.nix
Normal file
67
tests/modules/programs/webapps/custom-options.nix
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
programs.webApps = {
|
||||||
|
enable = true;
|
||||||
|
browser = pkgs.chromium;
|
||||||
|
|
||||||
|
apps = {
|
||||||
|
gmail = {
|
||||||
|
url = "https://mail.google.com";
|
||||||
|
name = "Gmail";
|
||||||
|
categories = [
|
||||||
|
"Office"
|
||||||
|
"Network"
|
||||||
|
"Email"
|
||||||
|
];
|
||||||
|
mimeTypes = [ "x-scheme-handler/mailto" ];
|
||||||
|
startupWmClass = "gmail-webapp";
|
||||||
|
extraOptions = {
|
||||||
|
"profile-directory" = "Profile 2";
|
||||||
|
"user-data-dir" = "/tmp/gmail-profile";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
simple = {
|
||||||
|
url = "https://example.com";
|
||||||
|
# Test minimal configuration
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
# Test Gmail with custom options
|
||||||
|
assertFileExists home-path/share/applications/webapp-gmail.desktop
|
||||||
|
|
||||||
|
# Check custom name and categories
|
||||||
|
assertFileRegex home-path/share/applications/webapp-gmail.desktop \
|
||||||
|
'Name=Gmail'
|
||||||
|
assertFileRegex home-path/share/applications/webapp-gmail.desktop \
|
||||||
|
'Categories=Office;Network;Email'
|
||||||
|
|
||||||
|
# Check MIME type support
|
||||||
|
assertFileRegex home-path/share/applications/webapp-gmail.desktop \
|
||||||
|
'MimeType=x-scheme-handler/mailto'
|
||||||
|
|
||||||
|
# Check custom StartupWMClass
|
||||||
|
assertFileRegex home-path/share/applications/webapp-gmail.desktop \
|
||||||
|
'StartupWMClass=gmail-webapp'
|
||||||
|
|
||||||
|
# Check extra browser options are included
|
||||||
|
assertFileRegex home-path/share/applications/webapp-gmail.desktop \
|
||||||
|
'Exec=.*--profile-directory=Profile\\ 2.*'
|
||||||
|
assertFileRegex home-path/share/applications/webapp-gmail.desktop \
|
||||||
|
'Exec=.*--user-data-dir=/tmp/gmail-profile.*'
|
||||||
|
|
||||||
|
# Test simple app with defaults
|
||||||
|
assertFileExists home-path/share/applications/webapp-simple.desktop
|
||||||
|
assertFileRegex home-path/share/applications/webapp-simple.desktop \
|
||||||
|
'Name=simple'
|
||||||
|
assertFileRegex home-path/share/applications/webapp-simple.desktop \
|
||||||
|
'Categories=Network;WebBrowser'
|
||||||
|
assertFileRegex home-path/share/applications/webapp-simple.desktop \
|
||||||
|
'StartupWMClass=chromium-webapp-simple'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
10
tests/modules/programs/webapps/default.nix
Normal file
10
tests/modules/programs/webapps/default.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
|
||||||
|
webapps-basic = ./basic.nix;
|
||||||
|
webapps-explicit-browser = ./explicit-browser.nix;
|
||||||
|
webapps-auto-detect = ./auto-detect.nix;
|
||||||
|
webapps-custom-options = ./custom-options.nix;
|
||||||
|
webapps-gmail-example = ./gmail-example.nix;
|
||||||
|
webapps-package-icons = ./package-icons.nix;
|
||||||
|
}
|
||||||
47
tests/modules/programs/webapps/explicit-browser.nix
Normal file
47
tests/modules/programs/webapps/explicit-browser.nix
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
programs.webApps = {
|
||||||
|
enable = true;
|
||||||
|
browser = pkgs.firefox;
|
||||||
|
|
||||||
|
apps = {
|
||||||
|
youtube = {
|
||||||
|
url = "https://youtube.com";
|
||||||
|
name = "YouTube";
|
||||||
|
icon = "applications-multimedia";
|
||||||
|
categories = [
|
||||||
|
"AudioVideo"
|
||||||
|
"Network"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
# Check that the desktop entry was created
|
||||||
|
assertFileExists home-path/share/applications/webapp-youtube.desktop
|
||||||
|
|
||||||
|
# Check custom name
|
||||||
|
assertFileRegex home-path/share/applications/webapp-youtube.desktop \
|
||||||
|
'Name=YouTube'
|
||||||
|
|
||||||
|
# Check Firefox exec (no --app mode for Firefox)
|
||||||
|
assertFileRegex home-path/share/applications/webapp-youtube.desktop \
|
||||||
|
'Exec=.*firefox.*https://youtube.com'
|
||||||
|
|
||||||
|
# Make sure it doesn't contain --app (Firefox doesn't support it)
|
||||||
|
assertFileNotRegex home-path/share/applications/webapp-youtube.desktop \
|
||||||
|
'Exec=.*--app.*'
|
||||||
|
|
||||||
|
# Check custom categories
|
||||||
|
assertFileRegex home-path/share/applications/webapp-youtube.desktop \
|
||||||
|
'Categories=AudioVideo;Network'
|
||||||
|
|
||||||
|
# Check icon
|
||||||
|
assertFileRegex home-path/share/applications/webapp-youtube.desktop \
|
||||||
|
'Icon=applications-multimedia'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
68
tests/modules/programs/webapps/gmail-example.nix
Normal file
68
tests/modules/programs/webapps/gmail-example.nix
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.webApps = {
|
||||||
|
enable = true;
|
||||||
|
browser = pkgs.chromium;
|
||||||
|
|
||||||
|
apps = {
|
||||||
|
# Method 1: Using theme icon names (most compatible)
|
||||||
|
gmail = {
|
||||||
|
url = "https://mail.google.com";
|
||||||
|
name = "Gmail";
|
||||||
|
icon = "mail-client";
|
||||||
|
categories = [
|
||||||
|
"Network"
|
||||||
|
"Email"
|
||||||
|
"Office"
|
||||||
|
];
|
||||||
|
mimeTypes = [ "x-scheme-handler/mailto" ];
|
||||||
|
startupWmClass = "gmail-webapp";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Method 2: Using general theme icon names
|
||||||
|
calendar = {
|
||||||
|
url = "https://calendar.google.com";
|
||||||
|
name = "Google Calendar";
|
||||||
|
icon = "calendar";
|
||||||
|
categories = [
|
||||||
|
"Office"
|
||||||
|
"Calendar"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Method 3: Using web browser icon as fallback
|
||||||
|
slack = {
|
||||||
|
url = "https://slack.com";
|
||||||
|
name = "Slack";
|
||||||
|
icon = "web-browser";
|
||||||
|
categories = [
|
||||||
|
"Network"
|
||||||
|
"Chat"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Method 4: Using application icon
|
||||||
|
discord = {
|
||||||
|
url = "https://discord.com/app";
|
||||||
|
name = "Discord";
|
||||||
|
icon = "application-x-executable";
|
||||||
|
categories = [
|
||||||
|
"Network"
|
||||||
|
"Chat"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Method 5: Using folder icon (always available)
|
||||||
|
github = {
|
||||||
|
url = "https://github.com";
|
||||||
|
name = "GitHub";
|
||||||
|
icon = "folder";
|
||||||
|
categories = [
|
||||||
|
"Development"
|
||||||
|
"Network"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
78
tests/modules/programs/webapps/package-icons.nix
Normal file
78
tests/modules/programs/webapps/package-icons.nix
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
xdg.enable = true;
|
||||||
|
|
||||||
|
programs.webApps = {
|
||||||
|
enable = true;
|
||||||
|
browser = pkgs.chromium;
|
||||||
|
|
||||||
|
apps = {
|
||||||
|
# Test with a package path using stubbed package
|
||||||
|
package-icon-test = {
|
||||||
|
url = "https://example.com";
|
||||||
|
name = "Package Icon Test";
|
||||||
|
# Use mock icon theme package created by test.stubs
|
||||||
|
icon = "${pkgs.mockicontheme}/share/icons/test.svg";
|
||||||
|
categories = [ "Network" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Test with string icon name for comparison
|
||||||
|
string-icon-test = {
|
||||||
|
url = "https://example2.com";
|
||||||
|
name = "String Icon Test";
|
||||||
|
icon = "folder";
|
||||||
|
categories = [ "Network" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Create a mock icon theme package for testing
|
||||||
|
test.stubs = {
|
||||||
|
mockicontheme = {
|
||||||
|
outPath = null;
|
||||||
|
buildScript = ''
|
||||||
|
mkdir -p $out/share/icons
|
||||||
|
echo "mock test icon" > $out/share/icons/test.svg
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Test that the desktop entries are created correctly
|
||||||
|
nmt.script = ''
|
||||||
|
# Check that desktop entries exist in the correct location
|
||||||
|
assertFileExists "$TESTED/home-path/share/applications/webapp-package-icon-test.desktop"
|
||||||
|
assertFileExists "$TESTED/home-path/share/applications/webapp-string-icon-test.desktop"
|
||||||
|
|
||||||
|
# Check that package-icon-test has the package-based icon path
|
||||||
|
# Note: test.stubs creates packages named "dummy" in the Nix store
|
||||||
|
assertFileContains "$TESTED/home-path/share/applications/webapp-package-icon-test.desktop" \
|
||||||
|
'Icon=/nix/store/'
|
||||||
|
assertFileContains "$TESTED/home-path/share/applications/webapp-package-icon-test.desktop" \
|
||||||
|
'dummy'
|
||||||
|
assertFileContains "$TESTED/home-path/share/applications/webapp-package-icon-test.desktop" \
|
||||||
|
'test.svg'
|
||||||
|
|
||||||
|
# Check that string-icon-test has the string icon name
|
||||||
|
assertFileContains "$TESTED/home-path/share/applications/webapp-string-icon-test.desktop" \
|
||||||
|
'Icon=folder'
|
||||||
|
|
||||||
|
# Verify the URLs are correct
|
||||||
|
assertFileContains "$TESTED/home-path/share/applications/webapp-package-icon-test.desktop" \
|
||||||
|
'https://example.com'
|
||||||
|
assertFileContains "$TESTED/home-path/share/applications/webapp-string-icon-test.desktop" \
|
||||||
|
'https://example2.com'
|
||||||
|
|
||||||
|
# Check the app mode launch commands are correct
|
||||||
|
assertFileContains "$TESTED/home-path/share/applications/webapp-package-icon-test.desktop" \
|
||||||
|
'Exec=@chromium@/bin/chromium --app=https://example.com'
|
||||||
|
assertFileContains "$TESTED/home-path/share/applications/webapp-string-icon-test.desktop" \
|
||||||
|
'Exec=@chromium@/bin/chromium --app=https://example2.com'
|
||||||
|
|
||||||
|
# Check the proper generic names are set
|
||||||
|
assertFileContains "$TESTED/home-path/share/applications/webapp-package-icon-test.desktop" \
|
||||||
|
'GenericName=Package Icon Test Web App'
|
||||||
|
assertFileContains "$TESTED/home-path/share/applications/webapp-string-icon-test.desktop" \
|
||||||
|
'GenericName=String Icon Test Web App'
|
||||||
|
'';
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue