import pytest from fastapi import HTTPException from fastapi.testclient import TestClient from sqlalchemy.orm import Session from app.models.business_type import BusinessType from app.models.plan import Plan from app.models.subscription import Subscription from app.models.tenant import Tenant from app.models.user import User from app.schemas.tenant import TenantCreate, TenantUpdate from app.services.tenant_service import ( assign_user_to_tenant, create_tenant, delete_tenant, get_tenant_by_id, get_tenant_list, update_tenant, ) @pytest.fixture def bt(db_session: Session): bt = BusinessType(code="TEST", name="Test") db_session.add(bt) db_session.flush() return bt @pytest.fixture def plan(db_session: Session): plan = Plan(code="TEST", name="Test", price=0) db_session.add(plan) db_session.flush() return plan class TestService: def test_create(self, db_session: Session, bt, plan): data = TenantCreate( name="Toko Saya", slug="toko-saya", business_type_id=bt.id, plan_id=plan.id, ) tenant = create_tenant(db_session, data) assert tenant.name == "Toko Saya" assert tenant.slug == "toko-saya" sub = db_session.query(Subscription).filter(Subscription.tenant_id == tenant.id).first() assert sub is not None def test_create_duplicate_slug(self, db_session: Session, bt, plan): create_tenant(db_session, TenantCreate(name="A", slug="same", business_type_id=bt.id, plan_id=plan.id)) with pytest.raises(HTTPException) as exc: create_tenant(db_session, TenantCreate(name="B", slug="same", business_type_id=bt.id, plan_id=plan.id)) assert exc.value.status_code == 409 def test_get_by_id(self, db_session: Session, bt, plan): tenant = create_tenant(db_session, TenantCreate(name="Get", slug="get", business_type_id=bt.id, plan_id=plan.id)) result = get_tenant_by_id(db_session, tenant.id) assert result.id == tenant.id def test_get_by_id_not_found(self, db_session: Session): with pytest.raises(HTTPException) as exc: get_tenant_by_id(db_session, "x") assert exc.value.status_code == 404 def test_list(self, db_session: Session, bt, plan): create_tenant(db_session, TenantCreate(name="A", slug="a", business_type_id=bt.id, plan_id=plan.id)) create_tenant(db_session, TenantCreate(name="B", slug="b", business_type_id=bt.id, plan_id=plan.id)) assert len(get_tenant_list(db_session)) == 2 def test_update(self, db_session: Session, bt, plan): tenant = create_tenant(db_session, TenantCreate(name="Old", slug="old", business_type_id=bt.id, plan_id=plan.id)) updated = update_tenant(db_session, tenant.id, TenantUpdate(name="New")) assert updated.name == "New" def test_update_conflict_slug(self, db_session: Session, bt, plan): create_tenant(db_session, TenantCreate(name="A", slug="taken", business_type_id=bt.id, plan_id=plan.id)) tenant = create_tenant(db_session, TenantCreate(name="B", slug="b", business_type_id=bt.id, plan_id=plan.id)) with pytest.raises(HTTPException) as exc: update_tenant(db_session, tenant.id, TenantUpdate(slug="taken")) assert exc.value.status_code == 409 def test_delete(self, db_session: Session, bt, plan): tenant = create_tenant(db_session, TenantCreate(name="Del", slug="del", business_type_id=bt.id, plan_id=plan.id)) delete_tenant(db_session, tenant.id) assert tenant.deleted_at is not None def test_assign_user(self, db_session: Session, bt, plan): tenant = create_tenant(db_session, TenantCreate(name="T", slug="t", business_type_id=bt.id, plan_id=plan.id)) user = User(email="u@ex.com", username="u", password="x") db_session.add(user) db_session.commit() result = assign_user_to_tenant(db_session, tenant.id, user.id) assert result["message"] == "User assigned to tenant" assert user.tenant_id == tenant.id assert user.status == "ACTIVE" def test_assign_user_tenant_not_found(self, db_session: Session): with pytest.raises(HTTPException) as exc: assign_user_to_tenant(db_session, "x", "y") assert exc.value.status_code == 404 class TestAPI: def test_create(self, client: TestClient, db_session: Session, bt, plan): resp = client.post("/v1/tenants/", json={ "name": "Toko", "slug": "toko", "business_type_id": bt.id, "plan_id": plan.id, }) assert resp.status_code == 201 def test_list(self, client: TestClient, db_session: Session, bt): db_session.add(Tenant(name="T", slug="t", business_type_id=bt.id)) db_session.commit() resp = client.get("/v1/tenants/") assert resp.status_code == 200 def test_not_found(self, client: TestClient): resp = client.get("/v1/tenants/x") assert resp.status_code == 404 def test_delete(self, client: TestClient, db_session: Session, bt, plan): from app.models.subscription import Subscription tenant = Tenant(name="D", slug="d", business_type_id=bt.id) db_session.add(tenant) db_session.flush() db_session.add(Subscription(tenant_id=tenant.id, plan_id=plan.id)) db_session.commit() resp = client.delete(f"/v1/tenants/{tenant.id}") assert resp.status_code == 204 def test_assign_user(self, client: TestClient, db_session: Session, bt, plan): tenant = Tenant(name="A", slug="a", business_type_id=bt.id) db_session.add(tenant) user = User(email="assign@ex.com", username="assign", password="x") db_session.add(user) db_session.commit() resp = client.post(f"/v1/tenants/{tenant.id}/assign-user?user_id={user.id}") assert resp.status_code == 200 assert resp.json()["message"] == "User assigned to tenant"