# tests/integration/api/v1/admin/test_modules.py """ Integration tests for admin module management endpoints. Tests the /api/v1/admin/modules/* and /api/v1/admin/module-config/* endpoints. All endpoints require super admin access. """ import pytest @pytest.mark.integration @pytest.mark.api @pytest.mark.admin @pytest.mark.modules class TestAdminModulesAPI: """Tests for admin module management endpoints.""" # ======================================================================== # List Modules Tests # ======================================================================== def test_list_all_modules(self, client, super_admin_headers): """Test super admin listing all modules.""" response = client.get("/api/v1/admin/modules", headers=super_admin_headers) assert response.status_code == 200 data = response.json() assert "modules" in data assert "total" in data assert data["total"] >= 10 # At least 10 modules defined # Check expected modules exist module_codes = [m["code"] for m in data["modules"]] assert "core" in module_codes assert "billing" in module_codes assert "inventory" in module_codes def test_list_modules_requires_super_admin(self, client, admin_headers): """Test that listing modules requires super admin.""" response = client.get("/api/v1/admin/modules", headers=admin_headers) # Should require super admin assert response.status_code == 403 def test_list_modules_unauthenticated(self, client): """Test that listing modules requires authentication.""" response = client.get("/api/v1/admin/modules") assert response.status_code == 401 # ======================================================================== # Get Platform Modules Tests # ======================================================================== def test_get_platform_modules(self, client, super_admin_headers, test_platform): """Test getting modules for a specific platform.""" response = client.get( f"/api/v1/admin/modules/platforms/{test_platform.id}", headers=super_admin_headers, ) assert response.status_code == 200 data = response.json() assert data["platform_id"] == test_platform.id assert data["platform_code"] == test_platform.code assert "modules" in data assert "enabled" in data assert "disabled" in data def test_get_platform_modules_not_found(self, client, super_admin_headers): """Test getting modules for non-existent platform.""" response = client.get( "/api/v1/admin/modules/platforms/99999", headers=super_admin_headers, ) assert response.status_code == 404 # ======================================================================== # Enable/Disable Module Tests # ======================================================================== def test_enable_module(self, client, super_admin_headers, test_platform, db): """Test enabling a module for a platform.""" # First disable the module via settings test_platform.settings = {"enabled_modules": ["core", "platform-admin"]} db.commit() response = client.post( f"/api/v1/admin/modules/platforms/{test_platform.id}/enable", headers=super_admin_headers, json={"module_code": "billing"}, ) assert response.status_code == 200 data = response.json() assert data["success"] is True assert "billing" in data["message"].lower() or "enabled" in data["message"].lower() def test_disable_module(self, client, super_admin_headers, test_platform, db): """Test disabling a module for a platform.""" # Ensure module is enabled test_platform.settings = {"enabled_modules": ["billing", "inventory"]} db.commit() response = client.post( f"/api/v1/admin/modules/platforms/{test_platform.id}/disable", headers=super_admin_headers, json={"module_code": "billing"}, ) assert response.status_code == 200 data = response.json() assert data["success"] is True def test_cannot_disable_core_module(self, client, super_admin_headers, test_platform): """Test that core modules cannot be disabled.""" response = client.post( f"/api/v1/admin/modules/platforms/{test_platform.id}/disable", headers=super_admin_headers, json={"module_code": "core"}, ) assert response.status_code == 400 data = response.json() assert "core" in data.get("message", "").lower() or "cannot" in data.get("message", "").lower() def test_enable_invalid_module(self, client, super_admin_headers, test_platform): """Test enabling a non-existent module.""" response = client.post( f"/api/v1/admin/modules/platforms/{test_platform.id}/enable", headers=super_admin_headers, json={"module_code": "invalid_module"}, ) assert response.status_code == 400 # ======================================================================== # Bulk Operations Tests # ======================================================================== def test_update_platform_modules(self, client, super_admin_headers, test_platform): """Test updating all enabled modules at once.""" response = client.put( f"/api/v1/admin/modules/platforms/{test_platform.id}", headers=super_admin_headers, json={"module_codes": ["billing", "inventory", "orders"]}, ) assert response.status_code == 200 data = response.json() assert data["platform_id"] == test_platform.id # Check that specified modules are enabled enabled_codes = [m["code"] for m in data["modules"] if m["is_enabled"]] assert "billing" in enabled_codes assert "inventory" in enabled_codes assert "orders" in enabled_codes # Core modules should always be enabled assert "core" in enabled_codes def test_enable_all_modules(self, client, super_admin_headers, test_platform): """Test enabling all modules for a platform.""" response = client.post( f"/api/v1/admin/modules/platforms/{test_platform.id}/enable-all", headers=super_admin_headers, ) assert response.status_code == 200 data = response.json() assert data["success"] is True assert data["enabled_count"] >= 10 def test_disable_optional_modules(self, client, super_admin_headers, test_platform): """Test disabling all optional modules.""" response = client.post( f"/api/v1/admin/modules/platforms/{test_platform.id}/disable-optional", headers=super_admin_headers, ) assert response.status_code == 200 data = response.json() assert data["success"] is True assert "core" in data["core_modules"] @pytest.mark.integration @pytest.mark.api @pytest.mark.admin @pytest.mark.modules class TestAdminModuleConfigAPI: """Tests for admin module configuration endpoints.""" # ======================================================================== # Get Module Config Tests # ======================================================================== def test_get_module_config(self, client, super_admin_headers, test_platform): """Test getting module configuration.""" response = client.get( f"/api/v1/admin/module-config/platforms/{test_platform.id}/modules/billing/config", headers=super_admin_headers, ) assert response.status_code == 200 data = response.json() assert data["module_code"] == "billing" assert "config" in data assert "schema_info" in data assert "defaults" in data def test_get_module_config_has_defaults(self, client, super_admin_headers, test_platform): """Test that module config includes default values.""" response = client.get( f"/api/v1/admin/module-config/platforms/{test_platform.id}/modules/billing/config", headers=super_admin_headers, ) assert response.status_code == 200 data = response.json() # Should have default billing config assert "stripe_mode" in data["config"] assert "default_trial_days" in data["config"] def test_get_module_config_invalid_module(self, client, super_admin_headers, test_platform): """Test getting config for invalid module.""" response = client.get( f"/api/v1/admin/module-config/platforms/{test_platform.id}/modules/invalid_module/config", headers=super_admin_headers, ) assert response.status_code == 400 # ======================================================================== # Update Module Config Tests # ======================================================================== def test_update_module_config(self, client, super_admin_headers, test_platform): """Test updating module configuration.""" response = client.put( f"/api/v1/admin/module-config/platforms/{test_platform.id}/modules/billing/config", headers=super_admin_headers, json={ "config": { "stripe_mode": "live", "default_trial_days": 7, } }, ) assert response.status_code == 200 data = response.json() assert data["config"]["stripe_mode"] == "live" assert data["config"]["default_trial_days"] == 7 def test_update_module_config_persists(self, client, super_admin_headers, test_platform): """Test that config updates persist across requests.""" # Update config client.put( f"/api/v1/admin/module-config/platforms/{test_platform.id}/modules/inventory/config", headers=super_admin_headers, json={ "config": { "low_stock_threshold": 25, } }, ) # Fetch again response = client.get( f"/api/v1/admin/module-config/platforms/{test_platform.id}/modules/inventory/config", headers=super_admin_headers, ) assert response.status_code == 200 data = response.json() assert data["config"]["low_stock_threshold"] == 25 # ======================================================================== # Reset Config Tests # ======================================================================== def test_reset_module_config(self, client, super_admin_headers, test_platform): """Test resetting module config to defaults.""" # First set custom config client.put( f"/api/v1/admin/module-config/platforms/{test_platform.id}/modules/billing/config", headers=super_admin_headers, json={ "config": { "stripe_mode": "live", "default_trial_days": 1, } }, ) # Reset to defaults response = client.post( f"/api/v1/admin/module-config/platforms/{test_platform.id}/modules/billing/reset", headers=super_admin_headers, ) assert response.status_code == 200 data = response.json() assert data["success"] is True # Config should be reset to defaults assert data["config"]["stripe_mode"] == "test" assert data["config"]["default_trial_days"] == 14 # ======================================================================== # Get Defaults Tests # ======================================================================== def test_get_config_defaults(self, client, super_admin_headers): """Test getting default config for a module.""" response = client.get( "/api/v1/admin/module-config/defaults/billing", headers=super_admin_headers, ) assert response.status_code == 200 data = response.json() assert data["module_code"] == "billing" assert "defaults" in data assert "schema_info" in data assert data["defaults"]["stripe_mode"] == "test"