diff --git a/tests/test_paths.py b/tests/test_paths.py new file mode 100644 index 0000000..757eca1 --- /dev/null +++ b/tests/test_paths.py @@ -0,0 +1,308 @@ +"""Tests for the PathResolver module.""" + +import pytest +from pathlib import Path +from unittest.mock import patch, MagicMock + +from development_hub.paths import PathResolver, paths +from development_hub.settings import Settings + + +class TestPathResolver: + """Test PathResolver path resolution.""" + + @pytest.fixture + def isolated_settings(self, tmp_path, monkeypatch): + """Create isolated settings for testing.""" + Settings._instance = None + PathResolver._instance = None + + monkeypatch.setattr(Settings, "_settings_file", tmp_path / "settings.json") + monkeypatch.setattr(Settings, "_session_file", tmp_path / "session.json") + + settings = Settings() + yield settings + + Settings._instance = None + PathResolver._instance = None + + def test_singleton_pattern(self): + """PathResolver is a singleton.""" + PathResolver._instance = None + + resolver1 = PathResolver() + resolver2 = PathResolver() + + assert resolver1 is resolver2 + + PathResolver._instance = None + + def test_projects_root_from_settings(self, isolated_settings, tmp_path): + """Projects root comes from settings.""" + isolated_settings.project_search_paths = [str(tmp_path / "my-projects")] + + resolver = PathResolver() + assert resolver.projects_root == tmp_path / "my-projects" + + def test_projects_root_default(self, isolated_settings, tmp_path): + """Projects root defaults to ~/Projects when not set.""" + isolated_settings.project_search_paths = [] + + resolver = PathResolver() + assert resolver.projects_root == Path.home() / "Projects" + + def test_docs_root_from_settings(self, isolated_settings, tmp_path): + """Docs root comes from settings.""" + isolated_settings.docs_mode = "standalone" + + resolver = PathResolver() + docs_root = resolver.docs_root + + assert "development-hub" in str(docs_root) + + def test_project_docs_dir(self, isolated_settings, tmp_path): + """Project docs dir returns docusaurus path.""" + project_docs = tmp_path / "project-docs" + project_docs.mkdir() + + isolated_settings.project_search_paths = [str(tmp_path)] + + resolver = PathResolver() + assert resolver.project_docs_dir == project_docs + + def test_project_docs_dir_none_when_not_exists(self, isolated_settings, tmp_path): + """Project docs dir is None when not configured.""" + isolated_settings.project_search_paths = [str(tmp_path)] + # No project-docs folder + + resolver = PathResolver() + assert resolver.project_docs_dir is None + + def test_progress_dir(self, isolated_settings): + """Progress dir comes from settings.""" + resolver = PathResolver() + progress = resolver.progress_dir + + assert isinstance(progress, Path) + + def test_build_script_when_exists(self, isolated_settings, tmp_path): + """Build script returns path when it exists.""" + project_docs = tmp_path / "project-docs" + scripts_dir = project_docs / "scripts" + scripts_dir.mkdir(parents=True) + + build_script = scripts_dir / "build-public-docs.sh" + build_script.touch() + + isolated_settings.project_search_paths = [str(tmp_path)] + + resolver = PathResolver() + assert resolver.build_script == build_script + + def test_build_script_none_when_not_exists(self, isolated_settings, tmp_path): + """Build script is None when it doesn't exist.""" + isolated_settings.project_search_paths = [str(tmp_path)] + + resolver = PathResolver() + assert resolver.build_script is None + + def test_project_docs_path(self, isolated_settings): + """project_docs_path returns correct path for project.""" + resolver = PathResolver() + + path = resolver.project_docs_path("my-project") + + assert path.name == "my-project" + assert "projects" in str(path) + + def test_git_url_not_configured(self, isolated_settings): + """git_url returns empty string when not configured.""" + resolver = PathResolver() + + assert resolver.git_url() == "" + assert resolver.git_url("owner", "repo") == "" + + def test_git_url_configured(self, isolated_settings): + """git_url returns correct URL when configured.""" + isolated_settings.git_host_type = "github" + isolated_settings.git_host_url = "https://github.com" + isolated_settings.git_host_owner = "testowner" + + resolver = PathResolver() + + assert resolver.git_url() == "https://github.com/testowner" + assert resolver.git_url("testowner", "testrepo") == "https://github.com/testowner/testrepo" + + def test_git_url_custom_owner(self, isolated_settings): + """git_url can use custom owner.""" + isolated_settings.git_host_type = "github" + isolated_settings.git_host_url = "https://github.com" + isolated_settings.git_host_owner = "default" + + resolver = PathResolver() + + assert resolver.git_url("custom", "repo") == "https://github.com/custom/repo" + + def test_pages_url_not_configured(self, isolated_settings): + """pages_url returns empty string when not configured.""" + resolver = PathResolver() + + assert resolver.pages_url() == "" + + def test_pages_url_configured(self, isolated_settings): + """pages_url returns correct URL when configured.""" + isolated_settings.git_host_owner = "testowner" + isolated_settings.pages_url = "https://pages.example.com" + + resolver = PathResolver() + + assert "pages.example.com" in resolver.pages_url() + assert "testowner" in resolver.pages_url() + + def test_is_docs_enabled(self, isolated_settings): + """is_docs_enabled reflects settings.""" + isolated_settings.docs_mode = "standalone" + + resolver = PathResolver() + assert resolver.is_docs_enabled == True + + def test_is_git_configured(self, isolated_settings): + """is_git_configured reflects settings.""" + resolver = PathResolver() + assert resolver.is_git_configured == False + + isolated_settings.git_host_type = "github" + isolated_settings.git_host_url = "https://github.com" + isolated_settings.git_host_owner = "user" + + assert resolver.is_git_configured == True + + def test_effective_docs_mode(self, isolated_settings, tmp_path): + """effective_docs_mode reflects settings.""" + isolated_settings.project_search_paths = [str(tmp_path)] + isolated_settings.docs_mode = "auto" + + resolver = PathResolver() + + # No project-docs, so standalone + assert resolver.effective_docs_mode == "standalone" + + # Create project-docs + (tmp_path / "project-docs").mkdir() + assert resolver.effective_docs_mode == "project-docs" + + +class TestCmdForgeAvailability: + """Test CmdForge availability checks.""" + + @pytest.fixture + def isolated_settings(self, tmp_path, monkeypatch): + """Create isolated settings for testing.""" + Settings._instance = None + PathResolver._instance = None + + monkeypatch.setattr(Settings, "_settings_file", tmp_path / "settings.json") + monkeypatch.setattr(Settings, "_session_file", tmp_path / "session.json") + + settings = Settings() + # Use isolated paths to prevent finding real CmdForge + settings.project_search_paths = [str(tmp_path)] + yield settings + + Settings._instance = None + PathResolver._instance = None + + def test_cmdforge_path_explicit(self, isolated_settings, tmp_path): + """CmdForge path from explicit setting.""" + cmdforge_dir = tmp_path / "CmdForge" + cmdforge_dir.mkdir() + + isolated_settings.cmdforge_path = cmdforge_dir + + resolver = PathResolver() + assert resolver.cmdforge_path == cmdforge_dir + + def test_cmdforge_executable_from_venv(self, isolated_settings, tmp_path): + """CmdForge executable found in venv.""" + cmdforge_dir = tmp_path / "CmdForge" + venv_bin = cmdforge_dir / ".venv" / "bin" + venv_bin.mkdir(parents=True) + + cmdforge_exe = venv_bin / "cmdforge" + cmdforge_exe.touch() + + isolated_settings.cmdforge_path = cmdforge_dir + + resolver = PathResolver() + assert resolver.cmdforge_executable == cmdforge_exe + + @patch("development_hub.paths.shutil.which") + def test_cmdforge_executable_from_path(self, mock_which, isolated_settings, tmp_path): + """CmdForge executable found in PATH when not in explicit location.""" + mock_which.return_value = "/usr/local/bin/cmdforge" + # Ensure no explicit cmdforge path is set + isolated_settings.cmdforge_path = None + + resolver = PathResolver() + exe = resolver.cmdforge_executable + + assert exe == Path("/usr/local/bin/cmdforge") + + @patch("development_hub.paths.shutil.which") + def test_cmdforge_executable_not_found(self, mock_which, isolated_settings, tmp_path): + """CmdForge executable None when not found.""" + mock_which.return_value = None + # Ensure no explicit cmdforge path is set + isolated_settings.cmdforge_path = None + + resolver = PathResolver() + assert resolver.cmdforge_executable is None + + @patch("development_hub.paths.shutil.which") + def test_is_cmdforge_available_false(self, mock_which, isolated_settings, tmp_path): + """is_cmdforge_available is False when not found.""" + mock_which.return_value = None + isolated_settings.cmdforge_path = None + + resolver = PathResolver() + assert resolver.is_cmdforge_available == False + + @patch("development_hub.paths.shutil.which") + def test_is_cmdforge_available_true(self, mock_which, isolated_settings, tmp_path): + """is_cmdforge_available is True when found in PATH.""" + mock_which.return_value = "/usr/bin/cmdforge" + isolated_settings.cmdforge_path = None + + resolver = PathResolver() + assert resolver.is_cmdforge_available == True + + +class TestGlobalPathsInstance: + """Test the global paths singleton instance.""" + + def test_paths_is_path_resolver(self): + """Global paths is a PathResolver instance.""" + assert isinstance(paths, PathResolver) + + def test_paths_has_expected_properties(self): + """Global paths has expected properties.""" + assert hasattr(paths, "projects_root") + assert hasattr(paths, "docs_root") + assert hasattr(paths, "project_docs_dir") + assert hasattr(paths, "progress_dir") + assert hasattr(paths, "build_script") + assert hasattr(paths, "cmdforge_path") + assert hasattr(paths, "cmdforge_executable") + assert hasattr(paths, "is_docs_enabled") + assert hasattr(paths, "is_cmdforge_available") + assert hasattr(paths, "is_git_configured") + + def test_paths_has_expected_methods(self): + """Global paths has expected methods.""" + assert callable(paths.project_docs_path) + assert callable(paths.git_url) + assert callable(paths.pages_url) + + +if __name__ == "__main__": + pytest.main([__file__, "-v"]) diff --git a/tests/test_settings.py b/tests/test_settings.py index 12c53d4..633fa2c 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -245,5 +245,291 @@ class TestGitHostSettings: assert settings.is_git_configured == False +class TestDocsModeSettings: + """Test documentation mode configuration.""" + + @pytest.fixture + def isolated_settings(self, tmp_path, monkeypatch): + """Create an isolated Settings instance.""" + Settings._instance = None + + monkeypatch.setattr(Settings, "_settings_file", tmp_path / "settings.json") + monkeypatch.setattr(Settings, "_session_file", tmp_path / "session.json") + + settings = Settings() + yield settings + + Settings._instance = None + + def test_default_docs_mode(self, isolated_settings): + """Default docs mode is auto.""" + settings = isolated_settings + assert settings.docs_mode == "auto" + + def test_set_docs_mode(self, isolated_settings): + """Can set docs mode.""" + settings = isolated_settings + + settings.docs_mode = "standalone" + assert settings.docs_mode == "standalone" + + settings.docs_mode = "project-docs" + assert settings.docs_mode == "project-docs" + + def test_effective_docs_mode_standalone_when_no_project_docs(self, isolated_settings, tmp_path): + """Effective mode is standalone when project-docs doesn't exist.""" + settings = isolated_settings + settings.project_search_paths = [str(tmp_path)] + + # No project-docs folder exists + assert settings.effective_docs_mode == "standalone" + + def test_effective_docs_mode_project_docs_when_exists(self, isolated_settings, tmp_path): + """Effective mode is project-docs when folder exists.""" + settings = isolated_settings + settings.project_search_paths = [str(tmp_path)] + + # Create project-docs folder + (tmp_path / "project-docs").mkdir() + + assert settings.effective_docs_mode == "project-docs" + + def test_explicit_mode_overrides_auto(self, isolated_settings, tmp_path): + """Explicit mode setting overrides auto-detection.""" + settings = isolated_settings + settings.project_search_paths = [str(tmp_path)] + + # Create project-docs (would trigger project-docs mode in auto) + (tmp_path / "project-docs").mkdir() + + # But explicitly set to standalone + settings.docs_mode = "standalone" + assert settings.effective_docs_mode == "standalone" + + def test_docs_root_standalone_mode(self, isolated_settings): + """Docs root in standalone mode uses local share.""" + settings = isolated_settings + settings.docs_mode = "standalone" + + docs_root = settings.docs_root + assert ".local/share/development-hub" in str(docs_root) + + def test_docusaurus_path_property(self, isolated_settings, tmp_path): + """Can set and get docusaurus path.""" + settings = isolated_settings + + settings.docusaurus_path = tmp_path / "my-docs" + assert settings.docusaurus_path == tmp_path / "my-docs" + + def test_pages_url_property(self, isolated_settings): + """Can set and get pages URL.""" + settings = isolated_settings + + settings.pages_url = "https://pages.example.com" + assert settings.pages_url == "https://pages.example.com" + + def test_pages_url_derived_from_gitea(self, isolated_settings): + """Pages URL can be derived from gitea URL.""" + settings = isolated_settings + + settings.git_host_type = "gitea" + settings.git_host_url = "https://gitea.example.com" + + # When not explicitly set, should derive + assert "pages.example.com" in settings.pages_url + + def test_is_docs_enabled_standalone(self, isolated_settings): + """Docs are always enabled in standalone mode.""" + settings = isolated_settings + settings.docs_mode = "standalone" + + assert settings.is_docs_enabled == True + + def test_cmdforge_path_property(self, isolated_settings, tmp_path): + """Can set and get cmdforge path.""" + settings = isolated_settings + + settings.cmdforge_path = tmp_path / "CmdForge" + assert settings.cmdforge_path == tmp_path / "CmdForge" + + def test_progress_dir_property(self, isolated_settings, tmp_path): + """Can set and get progress directory.""" + settings = isolated_settings + + settings.progress_dir = tmp_path / "progress" + assert settings.progress_dir == tmp_path / "progress" + + +class TestWorkspaceExportImport: + """Test workspace file export/import.""" + + @pytest.fixture + def isolated_settings(self, tmp_path, monkeypatch): + """Create an isolated Settings instance.""" + Settings._instance = None + + monkeypatch.setattr(Settings, "_settings_file", tmp_path / "settings.json") + monkeypatch.setattr(Settings, "_session_file", tmp_path / "session.json") + + settings = Settings() + yield settings + + Settings._instance = None + + def test_export_workspace_creates_file(self, isolated_settings, tmp_path): + """Export creates a YAML workspace file.""" + settings = isolated_settings + workspace_path = tmp_path / "workspace.yaml" + + settings.export_workspace(workspace_path) + + assert workspace_path.exists() + + def test_export_workspace_contains_required_fields(self, isolated_settings, tmp_path): + """Exported workspace contains required fields.""" + import yaml + + settings = isolated_settings + settings.project_search_paths = [str(tmp_path / "projects")] + workspace_path = tmp_path / "workspace.yaml" + + settings.export_workspace(workspace_path) + + with open(workspace_path) as f: + workspace = yaml.safe_load(f) + + assert "name" in workspace + assert "version" in workspace + assert workspace["version"] == 1 + assert "paths" in workspace + assert "projects_root" in workspace["paths"] + assert "documentation" in workspace + assert "features" in workspace + + def test_export_includes_git_hosting_when_configured(self, isolated_settings, tmp_path): + """Exported workspace includes git hosting when configured.""" + import yaml + + settings = isolated_settings + settings.git_host_type = "github" + settings.git_host_url = "https://github.com" + settings.git_host_owner = "testuser" + + workspace_path = tmp_path / "workspace.yaml" + settings.export_workspace(workspace_path) + + with open(workspace_path) as f: + workspace = yaml.safe_load(f) + + assert "git_hosting" in workspace + assert workspace["git_hosting"]["type"] == "github" + assert workspace["git_hosting"]["url"] == "https://github.com" + assert workspace["git_hosting"]["owner"] == "testuser" + + def test_import_workspace_sets_values(self, isolated_settings, tmp_path): + """Import workspace sets settings values.""" + import yaml + + settings = isolated_settings + + workspace = { + "name": "Test Workspace", + "version": 1, + "paths": { + "projects_root": str(tmp_path / "my-projects") + }, + "documentation": { + "mode": "standalone" + } + } + + workspace_path = tmp_path / "workspace.yaml" + with open(workspace_path, "w") as f: + yaml.dump(workspace, f) + + results = settings.import_workspace(workspace_path) + + assert "projects_root" in results["imported"] + assert settings.project_search_paths == [str(tmp_path / "my-projects")] + assert settings.docs_mode == "standalone" + + def test_import_workspace_sets_git_hosting(self, isolated_settings, tmp_path): + """Import workspace sets git hosting values.""" + import yaml + + settings = isolated_settings + + workspace = { + "name": "Test", + "version": 1, + "paths": {"projects_root": str(tmp_path)}, + "git_hosting": { + "type": "gitea", + "url": "https://git.example.com", + "owner": "myorg", + "pages_url": "https://pages.example.com" + } + } + + workspace_path = tmp_path / "workspace.yaml" + with open(workspace_path, "w") as f: + yaml.dump(workspace, f) + + settings.import_workspace(workspace_path) + + assert settings.git_host_type == "gitea" + assert settings.git_host_url == "https://git.example.com" + assert settings.git_host_owner == "myorg" + assert settings.pages_url == "https://pages.example.com" + + def test_import_marks_setup_completed(self, isolated_settings, tmp_path): + """Import workspace marks setup as completed.""" + import yaml + + settings = isolated_settings + + workspace = { + "name": "Test", + "version": 1, + "paths": {"projects_root": str(tmp_path)} + } + + workspace_path = tmp_path / "workspace.yaml" + with open(workspace_path, "w") as f: + yaml.dump(workspace, f) + + settings.import_workspace(workspace_path) + + assert settings.get("setup_completed") == True + + def test_export_import_round_trip(self, isolated_settings, tmp_path): + """Export and import preserves settings.""" + settings = isolated_settings + + # Configure settings + settings.project_search_paths = [str(tmp_path / "projects")] + settings.docs_mode = "project-docs" + settings.git_host_type = "gitlab" + settings.git_host_url = "https://gitlab.com" + settings.git_host_owner = "myuser" + + # Export + workspace_path = tmp_path / "workspace.yaml" + settings.export_workspace(workspace_path) + + # Reset settings + Settings._instance = None + new_settings = Settings() + + # Import + new_settings.import_workspace(workspace_path) + + assert new_settings.project_search_paths == [str(tmp_path / "projects")] + assert new_settings.docs_mode == "project-docs" + assert new_settings.git_host_type == "gitlab" + assert new_settings.git_host_url == "https://gitlab.com" + assert new_settings.git_host_owner == "myuser" + + if __name__ == "__main__": pytest.main([__file__, "-v"]) diff --git a/tests/test_wizard.py b/tests/test_wizard.py new file mode 100644 index 0000000..cee1077 --- /dev/null +++ b/tests/test_wizard.py @@ -0,0 +1,227 @@ +"""Tests for the SetupWizardDialog.""" + +import pytest +from pathlib import Path +from unittest.mock import patch, MagicMock + +from development_hub.settings import Settings + + +class TestSetupWizardStructure: + """Test SetupWizardDialog structure without Qt app.""" + + @pytest.fixture + def isolated_settings(self, tmp_path, monkeypatch): + """Create isolated settings for testing.""" + Settings._instance = None + + monkeypatch.setattr(Settings, "_settings_file", tmp_path / "settings.json") + monkeypatch.setattr(Settings, "_session_file", tmp_path / "session.json") + + settings = Settings() + yield settings + + Settings._instance = None + + def test_wizard_import_succeeds(self): + """SetupWizardDialog can be imported.""" + from development_hub.dialogs import SetupWizardDialog + assert SetupWizardDialog is not None + + def test_wizard_has_expected_methods(self): + """SetupWizardDialog has expected methods.""" + from development_hub.dialogs import SetupWizardDialog + + # Check for key methods + assert hasattr(SetupWizardDialog, "_create_welcome_page") + assert hasattr(SetupWizardDialog, "_create_simple_mode_page") + assert hasattr(SetupWizardDialog, "_create_docs_mode_page") + assert hasattr(SetupWizardDialog, "_create_import_page") + assert hasattr(SetupWizardDialog, "_finish_simple_mode") + assert hasattr(SetupWizardDialog, "_finish_docs_mode") + assert hasattr(SetupWizardDialog, "_finish_import") + + +class TestWizardSettingsIntegration: + """Test wizard settings integration logic.""" + + @pytest.fixture + def isolated_settings(self, tmp_path, monkeypatch): + """Create isolated settings for testing.""" + Settings._instance = None + + monkeypatch.setattr(Settings, "_settings_file", tmp_path / "settings.json") + monkeypatch.setattr(Settings, "_session_file", tmp_path / "session.json") + + settings = Settings() + yield settings + + Settings._instance = None + + def test_simple_mode_sets_standalone_docs(self, isolated_settings, tmp_path): + """Simple mode configuration sets standalone docs mode.""" + settings = isolated_settings + + # Simulate what _finish_simple_mode does + projects_path = tmp_path / "Projects" + projects_path.mkdir() + + settings.default_project_path = projects_path + settings.project_search_paths = [str(projects_path)] + settings.docs_mode = "standalone" + settings.set("setup_completed", True) + + assert settings.docs_mode == "standalone" + assert settings.get("setup_completed") == True + + def test_docs_mode_sets_project_docs(self, isolated_settings, tmp_path): + """Documentation mode configuration sets project-docs mode.""" + settings = isolated_settings + + # Simulate what _finish_docs_mode does + projects_path = tmp_path / "PycharmProjects" + projects_path.mkdir() + docusaurus_path = projects_path / "project-docs" + docusaurus_path.mkdir() + + settings.default_project_path = projects_path + settings.project_search_paths = [str(projects_path)] + settings.docs_mode = "project-docs" + settings.docusaurus_path = docusaurus_path + settings.auto_start_docs_server = True + settings.git_host_type = "gitea" + settings.git_host_url = "https://gitea.example.com" + settings.git_host_owner = "testuser" + settings.set("setup_completed", True) + + assert settings.docs_mode == "project-docs" + assert settings.docusaurus_path == docusaurus_path + assert settings.auto_start_docs_server == True + assert settings.is_git_configured == True + assert settings.get("setup_completed") == True + + def test_import_workspace_integration(self, isolated_settings, tmp_path): + """Import workspace correctly sets all values.""" + import yaml + + settings = isolated_settings + + # Create a workspace file + workspace = { + "name": "Test Workspace", + "version": 1, + "paths": { + "projects_root": str(tmp_path / "projects") + }, + "documentation": { + "mode": "project-docs", + "docusaurus_path": str(tmp_path / "docs"), + "auto_start_server": False + }, + "git_hosting": { + "type": "github", + "url": "https://github.com", + "owner": "myorg" + } + } + + workspace_path = tmp_path / "test-workspace.yaml" + with open(workspace_path, "w") as f: + yaml.dump(workspace, f) + + # Import (simulates _finish_import) + results = settings.import_workspace(workspace_path) + + assert settings.project_search_paths == [str(tmp_path / "projects")] + assert settings.docs_mode == "project-docs" + assert settings.docusaurus_path == tmp_path / "docs" + assert settings.auto_start_docs_server == False + assert settings.git_host_type == "github" + assert settings.git_host_owner == "myorg" + assert settings.get("setup_completed") == True + + +class TestWizardModeSelection: + """Test wizard mode selection logic.""" + + def test_mode_values(self): + """Test expected mode values.""" + modes = ["simple", "docs", "import"] + + # These are the modes used in the wizard + for mode in modes: + assert isinstance(mode, str) + + def test_docs_mode_settings_values(self): + """Test valid docs_mode setting values.""" + valid_modes = ["auto", "standalone", "project-docs"] + + for mode in valid_modes: + assert isinstance(mode, str) + + +class TestWizardGitTypeHandling: + """Test git type handling in wizard.""" + + @pytest.fixture + def isolated_settings(self, tmp_path, monkeypatch): + """Create isolated settings.""" + Settings._instance = None + + monkeypatch.setattr(Settings, "_settings_file", tmp_path / "settings.json") + monkeypatch.setattr(Settings, "_session_file", tmp_path / "session.json") + + settings = Settings() + yield settings + + Settings._instance = None + + def test_github_configuration(self, isolated_settings): + """GitHub configuration sets correct values.""" + settings = isolated_settings + + settings.git_host_type = "github" + settings.git_host_url = "https://github.com" + settings.git_host_owner = "testuser" + + assert settings.is_git_configured == True + assert settings.git_host_type == "github" + + def test_gitlab_configuration(self, isolated_settings): + """GitLab configuration sets correct values.""" + settings = isolated_settings + + settings.git_host_type = "gitlab" + settings.git_host_url = "https://gitlab.com" + settings.git_host_owner = "testuser" + + assert settings.is_git_configured == True + assert settings.git_host_type == "gitlab" + + def test_gitea_configuration(self, isolated_settings): + """Gitea configuration sets correct values.""" + settings = isolated_settings + + settings.git_host_type = "gitea" + settings.git_host_url = "https://gitea.example.com" + settings.git_host_owner = "testuser" + + assert settings.is_git_configured == True + assert settings.git_host_type == "gitea" + + def test_optional_git_in_simple_mode(self, isolated_settings, tmp_path): + """Git is optional in simple mode.""" + settings = isolated_settings + + # Simple mode without git + settings.docs_mode = "standalone" + settings.project_search_paths = [str(tmp_path)] + settings.set("setup_completed", True) + + # Git not configured is OK + assert settings.is_git_configured == False + assert settings.get("setup_completed") == True + + +if __name__ == "__main__": + pytest.main([__file__, "-v"])