source: flexoentity/tests/conftest.py@ 9592936

Last change on this file since 9592936 was 9592936, checked in by Enrico Schwass <ennoausberlin@…>, 8 weeks ago

adopt tests to reflect new design of Entity creation

  • Property mode set to 100644
File size: 3.3 KB
Line 
1# tests/stubs/single_choice_question.py
2import pytest
3from datetime import datetime
4from dataclasses import dataclass, field
5from typing import List
6from flexoentity import FlexOID, FlexoEntity, EntityType, EntityState, Domain, DomainManager
7
8@pytest.fixture
9def fixed_datetime(monkeypatch):
10 class FixedDate(datetime):
11 @classmethod
12 def now(cls, tz=None):
13 return datetime(2025, 11, 1, tzinfo=tz)
14 monkeypatch.setattr("flexoentity.id_factory.datetime", FixedDate)
15 return FixedDate
16
17@pytest.fixture(autouse=True)
18def reset_domain_manager():
19 DomainManager.clear() # You need to implement this
20 yield
21 DomainManager.clear()
22
23@pytest.fixture(autouse=True)
24def auto_domains():
25 Domain.with_domain_id("GENERAL", fullname="General Domain")
26 Domain.with_domain_id("TEST", fullname="Test Domain")
27
28@dataclass
29class AnswerOption:
30 id: str
31 text: str
32 points: float = 0.0
33
34 def to_dict(self):
35 return {"id": self.id, "text": self.text, "points": self.points}
36
37 @classmethod
38 def from_dict(cls, data):
39 return cls(
40 id=data.get("id", ""),
41 text=data.get("text", ""),
42 points=data.get("points", 0.0)
43 )
44
45
46@dataclass
47class SingleChoiceQuestion(FlexoEntity):
48 """A minimal stub to test FlexoEntity integration."""
49 ENTITY_TYPE = EntityType.ITEM
50
51 text: str = ""
52 options: List[AnswerOption] = field(default_factory=list)
53
54 def __post_init__(self):
55 # If no FlexOID yet, generate a draft ID now.
56 if not getattr(self, "flexo_id", None):
57 self.flexo_id = FlexOID.safe_generate(
58 domain_id=self.domain_id,
59 entity_type=SingleChoiceQuestion.ENTITY_TYPE.value, # 'I'
60 state=EntityState.DRAFT.value, # 'D'
61 text=self.text_seed or self.text,
62 version=1,
63 )
64
65 @classmethod
66 def default(cls):
67 return cls()
68
69 def to_dict(self):
70 base = super().to_dict()
71 base.update({
72 "text": self.text,
73 "options": [opt.to_dict() for opt in self.options],
74 })
75 return base
76
77 @property
78 def text_seed(self) -> str:
79 """Include answer options (and points) for deterministic ID generation."""
80
81 joined = "|".join(
82 f"{opt.text.strip()}:{opt.points}"
83 for opt in sorted(self.options, key=lambda o: o.text.strip().lower())
84 )
85 return f"{self.text}{joined}"
86
87 @classmethod
88 def from_dict(cls, data):
89 obj = cls(text=data.get("text", ""),
90 options=[AnswerOption.from_dict(o) for o in data.get("options", [])],
91 )
92 # restore FlexoEntity core fields
93 if "flexo_id" in data:
94 obj.flexo_id = FlexOID.to_dict(data["flexo_id"])
95 return obj
96
97@pytest.fixture
98def sample_domain():
99 domain_id = "PY_ARITHM"
100 return Domain.with_domain_id(domain_id=domain_id,
101 fullname="PYTHON_ARITHMETIC",
102 description="ALL ABOUT ARITHMETIC IN PYTHON")
103
104@pytest.fixture
105def sample_question(sample_domain):
106 q = SingleChoiceQuestion.with_domain_id(domain_id=sample_domain.domain_id,
107 text="What is 2 + 2?",
108 options=[])
109 q._update_fingerprint()
110 return q
Note: See TracBrowser for help on using the repository browser.