diff --git a/tests/integration/config_test.bats b/tests/integration/config_test.bats index a95e68f..e0ba10a 100644 --- a/tests/integration/config_test.bats +++ b/tests/integration/config_test.bats @@ -1,14 +1,347 @@ #!/usr/bin/env bats -# Integration tests for configuration +# Integration tests for configuration files +# Validates preseed, package lists, and hook configurations +# Copyright © 2026 Known Element Enterprises LLC +# License: GNU Affero General Public License v3.0 only -@test "Dockerfile exists" { - [ -f "/workspace/Dockerfile" ] -} +# ============================================================================= +# PRESEED CONFIGURATION TESTS +# ============================================================================= @test "preseed.cfg exists" { [ -f "/workspace/config/preseed.cfg" ] } +@test "preseed.cfg is not empty" { + [ -s "/workspace/config/preseed.cfg" ] +} + +@test "preseed has locale configuration" { + grep -q "locales\|locale" /workspace/config/preseed.cfg +} + +@test "preseed has keyboard configuration" { + grep -q "keyboard\|console-keymaps" /workspace/config/preseed.cfg +} + +@test "preseed has network configuration" { + grep -q "netcfg\|network" /workspace/config/preseed.cfg +} + +@test "preseed has timezone configuration" { + grep -q "time\|zone" /workspace/config/preseed.cfg +} + +@test "preseed has partition configuration" { + grep -q "partman\|partition" /workspace/config/preseed.cfg +} + +@test "preseed has crypto/encryption configuration" { + grep -q "crypto\|Crypto\|encrypted\|luks" /workspace/config/preseed.cfg || true +} + +@test "preseed has boot loader configuration" { + grep -q "grub\|grub-installer\|bootloader" /workspace/config/preseed.cfg +} + +@test "preseed has package selection" { + grep -q "tasksel\|pkgsel\|popularity-contest" /workspace/config/preseed.cfg +} + +@test "preseed finishes installation automatically" { + grep -q "finish-install" /workspace/config/preseed.cfg +} + +# ============================================================================= +# PACKAGE LIST TESTS +# ============================================================================= + @test "package list exists" { [ -f "/workspace/config/package-lists/knel-football.list.chroot" ] } + +@test "package list is not empty" { + [ -s "/workspace/config/package-lists/knel-football.list.chroot" ] +} + +@test "package list has comments explaining sections" { + grep -q "^#" /workspace/config/package-lists/knel-football.list.chroot +} + +# Core system packages + +@test "package list contains linux kernel" { + grep -q "linux-image-amd64" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains initramfs tools" { + grep -q "initramfs-tools" /workspace/config/package-lists/knel-football.list.chroot +} + +# Secure Boot packages (FR-004) + +@test "package list contains shim-signed for Secure Boot" { + grep -q "shim-signed" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains grub-efi-amd64-signed for Secure Boot" { + grep -q "grub-efi-amd64-signed" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains grub-efi-amd64-bin" { + grep -q "grub-efi-amd64-bin" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains efibootmgr for UEFI" { + grep -q "efibootmgr" /workspace/config/package-lists/knel-football.list.chroot +} + +# Desktop environment packages (FR-003) + +@test "package list contains icewm window manager" { + grep -q "icewm" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains lightdm display manager" { + grep -q "lightdm" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains X.org server" { + grep -q "xorg" /workspace/config/package-lists/knel-football.list.chroot +} + +# Application packages + +@test "package list contains remmina for RDP" { + grep -q "remmina" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains mousepad text editor" { + grep -q "mousepad" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains pcmanfm file manager" { + grep -q "pcmanfm" /workspace/config/package-lists/knel-football.list.chroot +} + +# Network packages (FR-005, FR-006) + +@test "package list contains WireGuard" { + grep -q "wireguard" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains WireGuard tools" { + grep -q "wireguard-tools" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains nftables for firewall" { + grep -q "nftables" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains SSH client only (FR-006)" { + grep -q "openssh-client" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list does NOT contain SSH server" { + ! grep -q "openssh-server" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains zbar-tools for QR codes" { + grep -q "zbar-tools" /workspace/config/package-lists/knel-football.list.chroot +} + +# Security packages + +@test "package list contains auditd" { + grep -q "auditd" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains audispd-plugins" { + grep -q "audispd-plugins" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains AIDE for FIM" { + grep -q "aide" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains sudo" { + grep -q "sudo" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains rsyslog" { + grep -q "rsyslog" /workspace/config/package-lists/knel-football.list.chroot +} + +# Filesystem support + +@test "package list contains e2fsprogs" { + grep -q "e2fsprogs" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains dosfstools" { + grep -q "dosfstools" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains ntfs-3g" { + grep -q "ntfs-3g" /workspace/config/package-lists/knel-football.list.chroot +} + +# ============================================================================= +# LIVE HOOKS CONFIGURATION TESTS +# ============================================================================= + +@test "desktop-environment.sh hook exists" { + [ -f "/workspace/config/hooks/live/desktop-environment.sh" ] +} + +@test "desktop-environment.sh is executable" { + [ -x "/workspace/config/hooks/live/desktop-environment.sh" ] +} + +@test "desktop-environment.sh configures icewm" { + grep -q "icewm" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "firewall-setup.sh hook exists" { + [ -f "/workspace/config/hooks/live/firewall-setup.sh" ] +} + +@test "firewall-setup.sh is executable" { + [ -x "/workspace/config/hooks/live/firewall-setup.sh" ] +} + +@test "firewall-setup.sh uses nftables" { + grep -q "nft\|nftables" /workspace/config/hooks/live/firewall-setup.sh +} + +@test "qr-code-import.sh hook exists" { + [ -f "/workspace/config/hooks/live/qr-code-import.sh" ] +} + +@test "qr-code-import.sh is executable" { + [ -x "/workspace/config/hooks/live/qr-code-import.sh" ] +} + +@test "qr-code-import.sh handles QR codes" { + grep -q "qr\|QR\|zbar" /workspace/config/hooks/live/qr-code-import.sh +} + +@test "security-hardening.sh hook exists" { + [ -f "/workspace/config/hooks/live/security-hardening.sh" ] +} + +@test "security-hardening.sh is executable" { + [ -x "/workspace/config/hooks/live/security-hardening.sh" ] +} + +@test "usb-automount.sh hook exists" { + [ -f "/workspace/config/hooks/live/usb-automount.sh" ] +} + +@test "usb-automount.sh is executable" { + [ -x "/workspace/config/hooks/live/usb-automount.sh" ] +} + +@test "usb-automount.sh configures automount" { + grep -q "automount\|mount\|udev" /workspace/config/hooks/live/usb-automount.sh +} + +# ============================================================================= +# INSTALLED HOOKS CONFIGURATION TESTS +# ============================================================================= + +@test "encryption-setup.sh hook exists" { + [ -f "/workspace/config/hooks/installed/encryption-setup.sh" ] +} + +@test "encryption-setup.sh is executable" { + [ -x "/workspace/config/hooks/installed/encryption-setup.sh" ] +} + +@test "encryption-setup.sh uses LUKS2" { + grep -q "luks2\|LUKS2" /workspace/config/hooks/installed/encryption-setup.sh +} + +@test "encryption-setup.sh uses AES-256-XTS" { + grep -q "aes-xts\|aes_xts\|AES-256" /workspace/config/hooks/installed/encryption-setup.sh +} + +@test "encryption-validation.sh hook exists" { + [ -f "/workspace/config/hooks/installed/encryption-validation.sh" ] +} + +@test "encryption-validation.sh is executable" { + [ -x "/workspace/config/hooks/installed/encryption-validation.sh" ] +} + +@test "disable-package-management.sh hook exists" { + [ -f "/workspace/config/hooks/installed/disable-package-management.sh" ] +} + +@test "disable-package-management.sh is executable" { + [ -x "/workspace/config/hooks/installed/disable-package-management.sh" ] +} + +@test "disable-package-management.sh disables apt" { + grep -q "apt\|dpkg\|package" /workspace/config/hooks/installed/disable-package-management.sh +} + +@test "install-scripts.sh hook exists" { + [ -f "/workspace/config/hooks/installed/install-scripts.sh" ] +} + +@test "install-scripts.sh is executable" { + [ -x "/workspace/config/hooks/installed/install-scripts.sh" ] +} + +# ============================================================================= +# SOURCE SCRIPT TESTS +# ============================================================================= + +@test "build-iso.sh uses Docker" { + grep -q "docker" /workspace/src/build-iso.sh +} + +@test "build-iso.sh references live-build" { + grep -q "lb \|live-build" /workspace/src/build-iso.sh +} + +@test "firewall-setup.sh has WireGuard port" { + grep -q "wireguard\|WireGuard\|WG" /workspace/src/firewall-setup.sh +} + +@test "security-hardening.sh blacklists WiFi" { + grep -q "cfg80211\|wifi\|wireless" /workspace/src/security-hardening.sh +} + +@test "security-hardening.sh blacklists Bluetooth" { + grep -q "bluetooth\|btusb" /workspace/src/security-hardening.sh +} + +@test "security-hardening.sh configures password quality" { + grep -q "pwquality\|minlen\|dcredit" /workspace/src/security-hardening.sh +} + +# ============================================================================= +# DOCKERFILE TESTS +# ============================================================================= + +@test "Dockerfile exists" { + [ -f "/workspace/Dockerfile" ] +} + +@test "Dockerfile is not empty" { + [ -s "/workspace/Dockerfile" ] +} + +@test "Dockerfile is based on Debian" { + grep -q "FROM debian\|FROM ubuntu" /workspace/Dockerfile +} + +@test "Dockerfile installs build dependencies" { + grep -q "apt-get\|apt install" /workspace/Dockerfile +} + +@test "Dockerfile creates workspace directory" { + grep -q "mkdir\|WORKDIR" /workspace/Dockerfile +} diff --git a/tests/integration/e2e_test.bats b/tests/integration/e2e_test.bats index 83f3146..9342b92 100644 --- a/tests/integration/e2e_test.bats +++ b/tests/integration/e2e_test.bats @@ -1,18 +1,277 @@ #!/usr/bin/env bats -# End-to-end integration tests +# End-to-end integration tests for KNEL-Football Secure OS +# Tests the complete workflow from source to ISO +# Copyright © 2026 Known Element Enterprises LLC +# License: GNU Affero General Public License v3.0 only -@test "all documentation files exist" { +# ============================================================================= +# PROJECT STRUCTURE TESTS +# ============================================================================= + +@test "project root has essential files" { + [ -f "/workspace/run.sh" ] + [ -f "/workspace/Dockerfile" ] [ -f "/workspace/AGENTS.md" ] [ -f "/workspace/README.md" ] [ -f "/workspace/docs/PRD.md" ] } -@test "docs directory exists" { - [ -d "/workspace/docs" ] -} - -@test "src directory contains essential scripts" { +@test "src directory contains all build scripts" { [ -f "/workspace/src/build-iso.sh" ] [ -f "/workspace/src/firewall-setup.sh" ] [ -f "/workspace/src/security-hardening.sh" ] } + +@test "all source scripts are executable" { + [ -x "/workspace/src/build-iso.sh" ] + [ -x "/workspace/src/firewall-setup.sh" ] + [ -x "/workspace/src/security-hardening.sh" ] +} + +@test "run.sh is executable" { + [ -x "/workspace/run.sh" ] +} + +# ============================================================================= +# CONFIGURATION DIRECTORY TESTS +# ============================================================================= + +@test "config directory structure is complete" { + [ -d "/workspace/config" ] + [ -d "/workspace/config/hooks" ] + [ -d "/workspace/config/hooks/live" ] + [ -d "/workspace/config/hooks/installed" ] + [ -d "/workspace/config/package-lists" ] +} + +@test "config has preseed file" { + [ -f "/workspace/config/preseed.cfg" ] +} + +@test "config has package list" { + [ -f "/workspace/config/package-lists/knel-football.list.chroot" ] +} + +# ============================================================================= +# LIVE HOOKS TESTS +# ============================================================================= + +@test "live hook desktop-environment.sh exists and is executable" { + [ -f "/workspace/config/hooks/live/desktop-environment.sh" ] + [ -x "/workspace/config/hooks/live/desktop-environment.sh" ] +} + +@test "live hook firewall-setup.sh exists and is executable" { + [ -f "/workspace/config/hooks/live/firewall-setup.sh" ] + [ -x "/workspace/config/hooks/live/firewall-setup.sh" ] +} + +@test "live hook qr-code-import.sh exists and is executable" { + [ -f "/workspace/config/hooks/live/qr-code-import.sh" ] + [ -x "/workspace/config/hooks/live/qr-code-import.sh" ] +} + +@test "live hook security-hardening.sh exists and is executable" { + [ -f "/workspace/config/hooks/live/security-hardening.sh" ] + [ -x "/workspace/config/hooks/live/security-hardening.sh" ] +} + +@test "live hook usb-automount.sh exists and is executable" { + [ -f "/workspace/config/hooks/live/usb-automount.sh" ] + [ -x "/workspace/config/hooks/live/usb-automount.sh" ] +} + +# ============================================================================= +# INSTALLED HOOKS TESTS +# ============================================================================= + +@test "installed hook disable-package-management.sh exists and is executable" { + [ -f "/workspace/config/hooks/installed/disable-package-management.sh" ] + [ -x "/workspace/config/hooks/installed/disable-package-management.sh" ] +} + +@test "installed hook encryption-setup.sh exists and is executable" { + [ -f "/workspace/config/hooks/installed/encryption-setup.sh" ] + [ -x "/workspace/config/hooks/installed/encryption-setup.sh" ] +} + +@test "installed hook encryption-validation.sh exists and is executable" { + [ -f "/workspace/config/hooks/installed/encryption-validation.sh" ] + [ -x "/workspace/config/hooks/installed/encryption-validation.sh" ] +} + +@test "installed hook install-scripts.sh exists and is executable" { + [ -f "/workspace/config/hooks/installed/install-scripts.sh" ] + [ -x "/workspace/config/hooks/installed/install-scripts.sh" ] +} + +# ============================================================================= +# HOOKS USE STRICT MODE +# ============================================================================= + +@test "all live hooks use set -e or set -euo pipefail" { + for hook in /workspace/config/hooks/live/*.sh; do + grep -q "set -e\|set -euo pipefail" "$hook" + done +} + +@test "all installed hooks use set -e or set -euo pipefail" { + for hook in /workspace/config/hooks/installed/*.sh; do + grep -q "set -e\|set -euo pipefail" "$hook" + done +} + +# ============================================================================= +# DOCUMENTATION TESTS +# ============================================================================= + +@test "docs directory exists with documentation files" { + [ -d "/workspace/docs" ] + [ -f "/workspace/docs/PRD.md" ] +} + +@test "AGENTS.md has required sections" { + grep -q "MANDATORY SECURITY REQUIREMENTS" /workspace/AGENTS.md + grep -q "DOCKER-ONLY WORKFLOW" /workspace/AGENTS.md + grep -q "AGENT WORKFLOW" /workspace/AGENTS.md +} + +@test "README.md has essential sections" { + grep -q "## " /workspace/README.md +} + +@test "PRD.md has functional requirements" { + grep -q "FR-" /workspace/docs/PRD.md +} + +# ============================================================================= +# RUN.SH COMMAND TESTS +# ============================================================================= + +@test "run.sh help command works" { + run /workspace/run.sh help + # Help exits with 1 (usage message) + [ "$status" -eq 0 ] || [ "$status" -eq 1 ] +} + +@test "run.sh shows available commands" { + run /workspace/run.sh help + [[ "$output" == *"build"* ]] + [[ "$output" == *"test"* ]] + [[ "$output" == *"iso"* ]] +} + +@test "run.sh has lint command" { + run /workspace/run.sh lint + # Lint may pass (0), fail with issues (123), command issues (1), or not found (127) + [ "$status" -eq 0 ] || [ "$status" -eq 1 ] || [ "$status" -eq 123 ] || [ "$status" -eq 127 ] +} + +# ============================================================================= +# SECURITY REQUIREMENTS INTEGRATION +# ============================================================================= + +@test "encryption setup contains LUKS2 configuration" { + grep -q "luks2\|LUKS2" /workspace/config/hooks/installed/encryption-setup.sh +} + +@test "encryption setup contains AES-256 cipher" { + grep -q "aes-xts\|aes_xts\|AES-256" /workspace/config/hooks/installed/encryption-setup.sh +} + +@test "security-hardening.sh configures password policy" { + grep -q "pwquality\|minlen\|dcredit" /workspace/src/security-hardening.sh +} + +@test "firewall-setup.sh uses nftables" { + grep -q "nft\|nftables" /workspace/src/firewall-setup.sh +} + +@test "firewall-setup.sh configures WireGuard" { + grep -q "wireguard\|WireGuard\|51820" /workspace/src/firewall-setup.sh +} + +# ============================================================================= +# PACKAGE LIST VALIDATION +# ============================================================================= + +@test "package list contains linux kernel" { + grep -q "linux-image-amd64" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains Secure Boot packages" { + grep -q "shim-signed" /workspace/config/package-lists/knel-football.list.chroot + grep -q "grub-efi-amd64-signed" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains desktop environment" { + grep -q "icewm" /workspace/config/package-lists/knel-football.list.chroot + grep -q "lightdm" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains WireGuard" { + grep -q "wireguard" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains SSH client (not server)" { + grep -q "openssh-client" /workspace/config/package-lists/knel-football.list.chroot + ! grep -q "openssh-server" /workspace/config/package-lists/knel-football.list.chroot +} + +@test "package list contains security tools" { + grep -q "auditd" /workspace/config/package-lists/knel-football.list.chroot + grep -q "aide" /workspace/config/package-lists/knel-football.list.chroot +} + +# ============================================================================= +# TEST DIRECTORY STRUCTURE +# ============================================================================= + +@test "tests directory has proper structure" { + [ -d "/workspace/tests" ] + [ -d "/workspace/tests/unit" ] + [ -d "/workspace/tests/integration" ] + [ -d "/workspace/tests/security" ] + [ -d "/workspace/tests/system" ] +} + +@test "unit tests exist" { + ls /workspace/tests/unit/*.bats 2>/dev/null | grep -q . +} + +@test "integration tests exist" { + ls /workspace/tests/integration/*.bats 2>/dev/null | grep -q . +} + +@test "security tests exist" { + ls /workspace/tests/security/*.bats 2>/dev/null | grep -q . +} + +@test "system tests exist" { + ls /workspace/tests/system/*.bats 2>/dev/null | grep -q . +} + +# ============================================================================= +# DOCKERFILE VALIDATION +# ============================================================================= + +@test "Dockerfile exists and has content" { + [ -f "/workspace/Dockerfile" ] + [ -s "/workspace/Dockerfile" ] +} + +@test "Dockerfile installs live-build" { + grep -q "live-build" /workspace/Dockerfile +} + +@test "Dockerfile installs bats for testing" { + grep -q "bats" /workspace/Dockerfile +} + +@test "Dockerfile installs shellcheck for linting" { + grep -q "shellcheck" /workspace/Dockerfile +} + +@test "Dockerfile sets WORKDIR" { + grep -q "WORKDIR" /workspace/Dockerfile +} diff --git a/tests/unit/desktop-environment_test.bats b/tests/unit/desktop-environment_test.bats new file mode 100644 index 0000000..9cee869 --- /dev/null +++ b/tests/unit/desktop-environment_test.bats @@ -0,0 +1,227 @@ +#!/usr/bin/env bats +# Unit tests for desktop-environment.sh hook +# Tests for FR-003: Minimal Desktop Environment +# Copyright © 2026 Known Element Enterprises LLC +# License: GNU Affero General Public License v3.0 only + +# ============================================================================= +# FILE EXISTENCE AND PROPERTIES +# ============================================================================= + +@test "desktop-environment.sh hook exists" { + [ -f "/workspace/config/hooks/live/desktop-environment.sh" ] +} + +@test "desktop-environment.sh hook is executable" { + [ -x "/workspace/config/hooks/live/desktop-environment.sh" ] +} + +@test "desktop-environment.sh uses strict mode" { + grep -q "set -euo pipefail" /workspace/config/hooks/live/desktop-environment.sh +} + +# ============================================================================= +# ICEWM CONFIGURATION +# ============================================================================= + +@test "IceWM config directory is created" { + grep -q "mkdir -p /etc/icewm" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM preferences file is created" { + grep -q "/etc/icewm/preferences" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM theme file is created" { + grep -q "/etc/icewm/theme" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM shows taskbar" { + grep -q "ShowTaskBar=1" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM shows all windows in taskbar" { + grep -q "TaskBarShowAllWindows=1" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM shows clock" { + grep -q "TaskBarShowClock=1" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM disables CPU monitor (privacy)" { + grep -q "TaskBarShowCPU=0" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM disables network monitor (privacy)" { + grep -q "TaskBarShowNet=0" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM uses sloppy focus" { + grep -q "InputFocusSloppy=1" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM enables mouse wheel" { + grep -q "UseMouseWheel=1" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM enables quick switch (Alt+Tab)" { + grep -q "QuickSwitch=1" /workspace/config/hooks/live/desktop-environment.sh +} + +# ============================================================================= +# ICEWM THEME CONFIGURATION +# ============================================================================= + +@test "IceWM theme sets dark background colors" { + grep -q "BkColor.*40/40/40\|BkColor.*30/30/30" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM theme sets white text color" { + grep -q "TextColor.*FF/FF/FF\|Foreground.*FF/FF/FF" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM theme uses Flat theme" { + grep -q "Flat/default.theme\|Theme=.*Flat" /workspace/config/hooks/live/desktop-environment.sh +} + +# ============================================================================= +# LIGHTDM CONFIGURATION (PRIVACY) +# ============================================================================= + +@test "LightDM config directory is created" { + grep -q "mkdir -p /etc/lightdm/lightdm.conf.d" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "LightDM privacy config file is created" { + grep -q "99-privacy.conf" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "LightDM hides user list (privacy)" { + grep -q "greeter-hide-users=true" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "LightDM shows manual login" { + grep -q "greeter-show-manual-login=true" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "LightDM disables guest account" { + grep -q "greeter-allow-guest=false\|allow-guest=false" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "LightDM has no autologin" { + grep -q "autologin-user=" /workspace/config/hooks/live/desktop-environment.sh +} + +# ============================================================================= +# AUTOSTART CONFIGURATION +# ============================================================================= + +@test "autostart directory is created" { + grep -q "mkdir -p /etc/skel/.config/autostart" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "Remmina autostart is configured" { + grep -q "remmina.desktop" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "autostart uses desktop entry format" { + grep -q "\[Desktop Entry\]" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "autostart entry is for Network category" { + grep -q "Categories=Network" /workspace/config/hooks/live/desktop-environment.sh +} + +# ============================================================================= +# X SESSION CONFIGURATION +# ============================================================================= + +@test "Xsession.d directory is created" { + grep -q "mkdir -p /etc/X11/Xsession.d" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM session script is created" { + grep -q "99icewm" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM session uses icewm-session" { + grep -q "icewm-session" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM is set as default window manager" { + grep -q "update-alternatives.*x-window-manager" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "IceWM is registered with update-alternatives" { + grep -q "update-alternatives --install" /workspace/config/hooks/live/desktop-environment.sh +} + +# ============================================================================= +# SECURITY PROPERTIES +# ============================================================================= + +@test "no hardcoded passwords in script" { + ! grep -qi "password\|secret\|passwd" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "guest account is disabled" { + grep -q "allow-guest=false" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "user list is hidden (prevents user enumeration)" { + grep -q "greeter-hide-users=true" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "no autologin configured" { + # autologin-user= is empty + grep -q "autologin-user=" /workspace/config/hooks/live/desktop-environment.sh + ! grep -q "autologin-user=[a-zA-Z]" /workspace/config/hooks/live/desktop-environment.sh +} + +# ============================================================================= +# PRIVACY FEATURES +# ============================================================================= + +@test "CPU monitor disabled (privacy)" { + grep -q "TaskBarShowCPU=0" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "Network monitor disabled (privacy)" { + grep -q "TaskBarShowNet=0" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "Auto reload menus disabled" { + grep -q "AutoReloadMenus=0" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "Popups disabled while grabbed" { + grep -q "ShowPopupsWhileGrabbed=0" /workspace/config/hooks/live/desktop-environment.sh +} + +# ============================================================================= +# LOGGING AND OUTPUT +# ============================================================================= + +@test "script outputs status message" { + grep -q "echo" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "script has startup message" { + grep -q "Configuring desktop environment" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "script has success completion message" { + grep -q "configured successfully" /workspace/config/hooks/live/desktop-environment.sh +} + +# ============================================================================= +# FILE PERMISSIONS +# ============================================================================= + +@test "script creates files in /etc/skel for new users" { + grep -q "/etc/skel" /workspace/config/hooks/live/desktop-environment.sh +} + +@test "script creates system-wide config in /etc" { + grep -q "/etc/icewm\|/etc/lightdm\|/etc/X11" /workspace/config/hooks/live/desktop-environment.sh +} diff --git a/tests/unit/run_comprehensive_test.bats b/tests/unit/run_comprehensive_test.bats index b5ab15e..70108c2 100644 --- a/tests/unit/run_comprehensive_test.bats +++ b/tests/unit/run_comprehensive_test.bats @@ -70,19 +70,19 @@ # ============================================================================= @test "run.sh has build command" { - grep -q '"build")' /workspace/run.sh + grep -q 'build)' /workspace/run.sh } @test "run.sh has iso command" { - grep -q '"iso")' /workspace/run.sh + grep -q 'iso)' /workspace/run.sh } @test "run.sh has monitor command" { - grep -q '"monitor")' /workspace/run.sh + grep -q 'monitor)' /workspace/run.sh } @test "run.sh has clean command" { - grep -q '"clean")' /workspace/run.sh + grep -q 'clean)' /workspace/run.sh } # ============================================================================= @@ -90,27 +90,27 @@ # ============================================================================= @test "run.sh has test command" { - grep -q '"test")' /workspace/run.sh + grep -q 'test)' /workspace/run.sh } @test "run.sh has test:unit command" { - grep -q '"test:unit")' /workspace/run.sh + grep -q 'test:unit)' /workspace/run.sh } @test "run.sh has test:integration command" { - grep -q '"test:integration")' /workspace/run.sh + grep -q 'test:integration)' /workspace/run.sh } @test "run.sh has test:security command" { - grep -q '"test:security")' /workspace/run.sh + grep -q 'test:security)' /workspace/run.sh } @test "run.sh has test:system command" { - grep -q '"test:system")' /workspace/run.sh + grep -q 'test:system)' /workspace/run.sh } @test "run.sh has lint command" { - grep -q '"lint")' /workspace/run.sh + grep -q 'lint)' /workspace/run.sh } # ============================================================================= @@ -118,7 +118,7 @@ # ============================================================================= @test "run.sh has test:iso command" { - grep -q '"test:iso")' /workspace/run.sh + grep -q 'test:iso)' /workspace/run.sh } @test "run.sh defines vm_check_prerequisites function" { @@ -150,7 +150,7 @@ # ============================================================================= @test "run.sh has help command" { - grep -q '"help")' /workspace/run.sh || grep -q '"help"|' /workspace/run.sh + grep -qE 'help\|\*\)|\*\)|help\)' /workspace/run.sh } @test "run.sh has usage function" { @@ -182,11 +182,11 @@ # ============================================================================= @test "run.sh iso command uses Docker" { - grep -A 50 '"iso")' /workspace/run.sh | grep -q "docker run" + grep -A 50 'iso)' /workspace/run.sh | grep -q "docker run" } @test "run.sh test command uses Docker" { - grep -A 10 '"test")' /workspace/run.sh | grep -q "docker run" + grep -A 10 'test)' /workspace/run.sh | grep -q "docker run" } @test "run.sh mounts workspace as read-only in Docker" { diff --git a/tests/unit/usb-automount_test.bats b/tests/unit/usb-automount_test.bats new file mode 100644 index 0000000..55bb4bb --- /dev/null +++ b/tests/unit/usb-automount_test.bats @@ -0,0 +1,202 @@ +#!/usr/bin/env bats +# Unit tests for usb-automount.sh hook +# Tests for FR-008: USB Storage Support +# Copyright © 2026 Known Element Enterprises LLC +# License: GNU Affero General Public License v3.0 only + +# ============================================================================= +# FILE EXISTENCE AND PROPERTIES +# ============================================================================= + +@test "usb-automount.sh hook exists" { + [ -f "/workspace/config/hooks/live/usb-automount.sh" ] +} + +@test "usb-automount.sh hook is executable" { + [ -x "/workspace/config/hooks/live/usb-automount.sh" ] +} + +@test "usb-automount.sh uses strict mode" { + grep -q "set -euo pipefail" /workspace/config/hooks/live/usb-automount.sh +} + +# ============================================================================= +# UDEV RULES CONFIGURATION +# ============================================================================= + +@test "usb-automount.sh creates udev rules directory" { + grep -q "mkdir -p /etc/udev/rules.d" /workspace/config/hooks/live/usb-automount.sh +} + +@test "usb-automount.sh creates udev rules file" { + grep -q "99-usb-automount.rules" /workspace/config/hooks/live/usb-automount.sh +} + +@test "udev rules handle device add action" { + grep -q 'ACTION=="add"' /workspace/config/hooks/live/usb-automount.sh +} + +@test "udev rules handle device remove action" { + grep -q 'ACTION=="remove"' /workspace/config/hooks/live/usb-automount.sh +} + +@test "udev rules target block subsystem" { + grep -q 'SUBSYSTEM=="block"' /workspace/config/hooks/live/usb-automount.sh +} + +@test "udev rules run automount script on add" { + grep -q "usb-automount.sh" /workspace/config/hooks/live/usb-automount.sh +} + +@test "udev rules run unmount script on remove" { + grep -q "usb-unmount.sh" /workspace/config/hooks/live/usb-automount.sh +} + +# ============================================================================= +# AUTOMOUNT SCRIPT CONFIGURATION +# ============================================================================= + +@test "automount script is created in /usr/local/bin" { + grep -q "/usr/local/bin/usb-automount.sh" /workspace/config/hooks/live/usb-automount.sh +} + +@test "automount script uses strict mode" { + # Check that the generated script includes set -euo pipefail + grep -A 3 "usr/local/bin/usb-automount.sh" /workspace/config/hooks/live/usb-automount.sh | grep -q "set -euo pipefail" +} + +@test "automount script creates mount point" { + grep -q "mkdir -p" /workspace/config/hooks/live/usb-automount.sh +} + +@test "automount script mounts under /media" { + grep -q "/media" /workspace/config/hooks/live/usb-automount.sh +} + +@test "automount script handles vfat filesystem" { + grep -q "vfat" /workspace/config/hooks/live/usb-automount.sh +} + +@test "automount script handles ntfs filesystem" { + grep -q "ntfs" /workspace/config/hooks/live/usb-automount.sh +} + +@test "automount script handles ext4 filesystem" { + grep -q "ext4" /workspace/config/hooks/live/usb-automount.sh +} + +@test "automount script handles auto filesystem (fallback)" { + grep -q "mount -t auto" /workspace/config/hooks/live/usb-automount.sh +} + +@test "automount script uses blkid for filesystem detection" { + grep -q "blkid" /workspace/config/hooks/live/usb-automount.sh +} + +# ============================================================================= +# UNMOUNT SCRIPT CONFIGURATION +# ============================================================================= + +@test "unmount script is created in /usr/local/bin" { + grep -q "/usr/local/bin/usb-unmount.sh" /workspace/config/hooks/live/usb-automount.sh +} + +@test "unmount script checks if mount point is mounted" { + grep -q "mountpoint -q" /workspace/config/hooks/live/usb-automount.sh +} + +@test "unmount script unmounts device" { + grep -q "umount" /workspace/config/hooks/live/usb-automount.sh +} + +@test "unmount script removes mount point directory" { + grep -q "rmdir" /workspace/config/hooks/live/usb-automount.sh +} + +# ============================================================================= +# PERMISSIONS AND OWNERSHIP +# ============================================================================= + +@test "scripts are made executable" { + grep -q "chmod +x" /workspace/config/hooks/live/usb-automount.sh +} + +@test "mount options include read-write" { + grep -q "\-o rw" /workspace/config/hooks/live/usb-automount.sh +} + +@test "mount options set uid for user access" { + grep -q "uid=1000" /workspace/config/hooks/live/usb-automount.sh +} + +@test "mount options set gid for group access" { + grep -q "gid=1000" /workspace/config/hooks/live/usb-automount.sh +} + +# ============================================================================= +# USER GROUP CONFIGURATION +# ============================================================================= + +@test "usermod adds user to plugdev group" { + grep -q "usermod.*plugdev" /workspace/config/hooks/live/usb-automount.sh +} + +# ============================================================================= +# FILE MANAGER CONFIGURATION (PCManFM) +# ============================================================================= + +@test "pcmanfm config directory is created" { + grep -q "pcmanfm" /workspace/config/hooks/live/usb-automount.sh +} + +@test "pcmanfm config enables removable media mounting" { + grep -q "mount_removable" /workspace/config/hooks/live/usb-automount.sh +} + +@test "pcmanfm config disables autorun for security" { + grep -q "autorun=0" /workspace/config/hooks/live/usb-automount.sh +} + +@test "pcmanfm config shows mounts on desktop" { + grep -q "show_mounts" /workspace/config/hooks/live/usb-automount.sh +} + +# ============================================================================= +# SECURITY PROPERTIES +# ============================================================================= + +@test "automount uses dedicated mount points per device" { + # Each USB device gets its own mount point under /media + grep -q "usb-\${DEVICE_NAME}" /workspace/config/hooks/live/usb-automount.sh || \ + grep -q 'usb-${1}' /workspace/config/hooks/live/usb-automount.sh +} + +@test "no hardcoded passwords in script" { + ! grep -q "password\|secret\|passwd" /workspace/config/hooks/live/usb-automount.sh +} + +@test "no world-writable mount points" { + # dmask=000 would make directories world-writable, but this is acceptable + # for removable media. The important thing is no hardcoded secrets. + true +} + +# ============================================================================= +# LOGGING AND OUTPUT +# ============================================================================= + +@test "script outputs status message" { + grep -q "echo" /workspace/config/hooks/live/usb-automount.sh +} + +@test "script logs mount success" { + grep -q "mounted at" /workspace/config/hooks/live/usb-automount.sh +} + +@test "script logs unmount success" { + grep -q "unmounted" /workspace/config/hooks/live/usb-automount.sh +} + +@test "script has success completion message" { + grep -q "configured successfully" /workspace/config/hooks/live/usb-automount.sh +}