Spaces:
Sleeping
Sleeping
| """ | |
| Unit Tests β Assessment & Outlet Pydantic Schemas | |
| Tests: | |
| - AssessmentCreate: required fields, validation (score range, category) | |
| - AssessmentResponse: ORM β Pydantic round-trip | |
| - OutletCreate: required fields, validation | |
| - OutletResponse: ORM β Pydantic round-trip | |
| """ | |
| from datetime import datetime, timezone | |
| import pytest | |
| from pydantic import ValidationError | |
| from models.assessment_model import Assessment, AssessmentCreate, AssessmentResponse | |
| from models.outlet_model import Outlet, OutletCreate, OutletResponse | |
| # βββββββββββββββββββββββββββββββββββββββββββ | |
| # AssessmentCreate | |
| # βββββββββββββββββββββββββββββββββββββββββββ | |
| class TestAssessmentCreate: | |
| def _valid(self, **overrides): | |
| return { | |
| "category": "A", | |
| "item_no": 1, | |
| "criteria": "Welcoming Kasir", | |
| "score": 4.0, | |
| "raw_value": "4", | |
| **overrides, | |
| } | |
| def test_valid_minimal(self): | |
| a = AssessmentCreate(**self._valid()) | |
| assert a.category == "A" | |
| assert a.item_no == 1 | |
| assert a.score == 4.0 | |
| assert a.notes is None | |
| def test_valid_with_notes(self): | |
| a = AssessmentCreate(**self._valid(notes="Sangat baik", description="Kasir ramah")) | |
| assert a.notes == "Sangat baik" | |
| assert a.description == "Kasir ramah" | |
| def test_category_required(self): | |
| data = self._valid() | |
| del data["category"] | |
| with pytest.raises(ValidationError) as exc_info: | |
| AssessmentCreate(**data) | |
| assert any(e["loc"] == ("category",) for e in exc_info.value.errors()) | |
| def test_category_max_length_1(self): | |
| with pytest.raises(ValidationError): | |
| AssessmentCreate(**self._valid(category="AB")) | |
| def test_category_empty_string_invalid(self): | |
| with pytest.raises(ValidationError): | |
| AssessmentCreate(**self._valid(category="")) | |
| def test_score_below_minimum(self): | |
| with pytest.raises(ValidationError): | |
| AssessmentCreate(**self._valid(score=0.5)) | |
| def test_score_above_maximum(self): | |
| with pytest.raises(ValidationError): | |
| AssessmentCreate(**self._valid(score=5.5)) | |
| def test_score_boundary_min(self): | |
| a = AssessmentCreate(**self._valid(score=1.0)) | |
| assert a.score == 1.0 | |
| def test_score_boundary_max(self): | |
| a = AssessmentCreate(**self._valid(score=5.0)) | |
| assert a.score == 5.0 | |
| def test_item_no_below_minimum(self): | |
| with pytest.raises(ValidationError): | |
| AssessmentCreate(**self._valid(item_no=0)) | |
| def test_item_no_above_maximum(self): | |
| with pytest.raises(ValidationError): | |
| AssessmentCreate(**self._valid(item_no=11)) | |
| def test_criteria_required(self): | |
| data = self._valid() | |
| del data["criteria"] | |
| with pytest.raises(ValidationError): | |
| AssessmentCreate(**data) | |
| def test_criteria_empty_invalid(self): | |
| with pytest.raises(ValidationError): | |
| AssessmentCreate(**self._valid(criteria="")) | |
| def test_criteria_max_length(self): | |
| with pytest.raises(ValidationError): | |
| AssessmentCreate(**self._valid(criteria="x" * 501)) | |
| # βββββββββββββββββββββββββββββββββββββββββββ | |
| # AssessmentResponse β ORM round-trip | |
| # βββββββββββββββββββββββββββββββββββββββββββ | |
| class TestAssessmentResponse: | |
| async def test_from_orm(self, sample_assessment: Assessment): | |
| resp = AssessmentResponse.model_validate(sample_assessment) | |
| assert str(resp.id) == str(sample_assessment.id) | |
| assert resp.category == "A" | |
| assert resp.item_no == 1 | |
| assert resp.score == 4.0 | |
| assert resp.raw_value == "4" | |
| assert resp.notes == "Baik" | |
| # βββββββββββββββββββββββββββββββββββββββββββ | |
| # OutletCreate | |
| # βββββββββββββββββββββββββββββββββββββββββββ | |
| class TestOutletCreate: | |
| def test_valid_minimal(self): | |
| o = OutletCreate(name="Outlet A") | |
| assert o.name == "Outlet A" | |
| assert o.location is None | |
| assert o.description is None | |
| def test_valid_full(self): | |
| o = OutletCreate( | |
| name="Outlet B", | |
| location="Jl. Merdeka", | |
| description="Outlet cabang", | |
| ) | |
| assert o.location == "Jl. Merdeka" | |
| def test_name_required(self): | |
| with pytest.raises(ValidationError) as exc_info: | |
| OutletCreate() | |
| assert any(e["loc"] == ("name",) for e in exc_info.value.errors()) | |
| def test_name_empty_invalid(self): | |
| with pytest.raises(ValidationError): | |
| OutletCreate(name="") | |
| def test_name_max_length(self): | |
| with pytest.raises(ValidationError): | |
| OutletCreate(name="x" * 256) | |
| def test_location_max_length(self): | |
| with pytest.raises(ValidationError): | |
| OutletCreate(name="OK", location="L" * 256) | |
| # βββββββββββββββββββββββββββββββββββββββββββ | |
| # OutletResponse β ORM round-trip | |
| # βββββββββββββββββββββββββββββββββββββββββββ | |
| class TestOutletResponse: | |
| async def test_from_orm(self, sample_outlet: Outlet): | |
| resp = OutletResponse.model_validate(sample_outlet) | |
| assert str(resp.id) == str(sample_outlet.id) | |
| assert resp.name == "Outlet Gedung A" | |
| assert resp.location == "Jl. Sudirman No. 1" | |