from __future__ import annotations from yuxi.channels.adapters.nextcloudtalk.setup_wizard import ( build_config_from_wizard, generate_wizard_steps, validate_step, ) class TestGenerateWizardSteps: def test_returns_list(self): steps = generate_wizard_steps() assert isinstance(steps, list) assert len(steps) >= 5 def test_step_structure(self): steps = generate_wizard_steps() for step in steps: assert "step" in step assert "title" in step assert "description" in step class TestValidateStep: def test_unknown_step(self): result = validate_step(999, {}) assert result["valid"] is False assert "Unknown step" in result["error"] def test_step_1_empty_url(self): result = validate_step(1, {"server_url": ""}) assert result["valid"] is False assert any("Server URL" in e for e in result.get("errors", [])) def test_step_1_valid_url(self): result = validate_step(1, {"server_url": "https://cloud.example.com"}) assert result["valid"] is True def test_step_1_invalid_url_scheme(self): result = validate_step(1, {"server_url": "ftp://cloud.example.com"}) assert result["valid"] is False def test_step_1_http_url(self): result = validate_step(1, {"server_url": "http://cloud.example.com"}) assert result["valid"] is True def test_step_2_missing_bot_user(self): result = validate_step(2, {"bot_user": "", "app_password": "secret"}) assert result["valid"] is False def test_step_2_missing_app_password(self): result = validate_step(2, {"bot_user": "bot", "app_password": ""}) assert result["valid"] is False def test_step_2_valid(self): result = validate_step(2, {"bot_user": "bot", "app_password": "secret"}) assert result["valid"] is True def test_step_3_always_valid(self): result = validate_step(3, {}) assert result["valid"] is True def test_step_4_empty_policy_valid(self): result = validate_step(4, {"dm_policy": ""}) assert result["valid"] is True def test_step_4_valid_policies(self): for policy in ("open", "pairing", "allowlist", "disabled"): result = validate_step(4, {"dm_policy": policy}) assert result["valid"] is True def test_step_4_invalid_policy(self): result = validate_step(4, {"dm_policy": "invalid"}) assert result["valid"] is False def test_step_5_valid(self): result = validate_step(5, {"allow_from": ["nc:user-1", "nc:user-2"]}) assert result["valid"] is True def test_step_5_invalid_format(self): result = validate_step(5, {"allow_from": ["bad-format"]}) assert result["valid"] is False assert any("nc:" in e for e in result.get("errors", [])) def test_step_5_empty_list(self): result = validate_step(5, {"allow_from": []}) assert result["valid"] is True class TestBuildConfigFromWizard: def test_minimal_config(self): data = { "server_url": "https://cloud.example.com", "bot_user": "bot", "app_password": "secret", } config = build_config_from_wizard(data) assert config["server_url"] == "https://cloud.example.com" assert config["bot_user"] == "bot" assert config["app_password"] == "secret" assert config["dm_policy"] == "pairing" assert config["try_websocket"] is True def test_strips_trailing_slash(self): config = build_config_from_wizard({ "server_url": "https://cloud.example.com/", "bot_user": "bot", "app_password": "secret", }) assert config["server_url"] == "https://cloud.example.com" def test_with_api_credentials(self): config = build_config_from_wizard({ "server_url": "https://cloud.example.com", "bot_user": "bot", "app_password": "secret", "api_user": "api_bot", "api_password": "api_secret", }) assert config["api_user"] == "api_bot" assert config["api_password"] == "api_secret" def test_with_allow_from(self): config = build_config_from_wizard({ "server_url": "https://cloud.example.com", "bot_user": "bot", "app_password": "secret", "allow_from": ["nc:user-1"], }) assert config["allow_from"] == ["nc:user-1"] def test_custom_dm_policy(self): config = build_config_from_wizard({ "server_url": "https://cloud.example.com", "bot_user": "bot", "app_password": "secret", "dm_policy": "open", }) assert config["dm_policy"] == "open"