source: flexoentity/tests/conftest.py@ fd1913f

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

version logic simplified - parsed renamed to to_dict

  • 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
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
18@dataclass
19class AnswerOption:
20 id: str
21 text: str
22 points: float = 0.0
23
24 def to_dict(self):
25 return {"id": self.id, "text": self.text, "points": self.points}
26
27 @classmethod
28 def from_dict(cls, data):
29 return cls(
30 id=data.get("id", ""),
31 text=data.get("text", ""),
32 points=data.get("points", 0.0)
33 )
34
35
36@dataclass
37class SingleChoiceQuestion(FlexoEntity):
38 """A minimal stub to test FlexoEntity integration."""
39 ENTITY_TYPE = EntityType.ITEM
40
41 text: str = ""
42 options: List[AnswerOption] = field(default_factory=list)
43
44 def __post_init__(self):
45 # If no FlexOID yet, generate a draft ID now.
46 if not getattr(self, "flexo_id", None):
47 self.flexo_id = FlexOID.safe_generate(
48 domain=self.domain_id,
49 entity_type=SingleChoiceQuestion.ENTITY_TYPE.value, # 'I'
50 estate=EntityState.DRAFT.value, # 'D'
51 text=self.text_seed or self.text,
52 version=1,
53 )
54
55 @classmethod
56 def default(cls):
57 return cls()
58
59 def to_dict(self):
60 base = super().to_dict()
61 base.update({
62 "text": self.text,
63 "options": [opt.to_dict() for opt in self.options],
64 })
65 return base
66
67 @property
68 def text_seed(self) -> str:
69 """Include answer options (and points) for deterministic ID generation."""
70
71 joined = "|".join(
72 f"{opt.text.strip()}:{opt.points}"
73 for opt in sorted(self.options, key=lambda o: o.text.strip().lower())
74 )
75 return f"{self.text}{joined}"
76
77 @classmethod
78 def from_dict(cls, data):
79 obj = cls(text=data.get("text", ""),
80 options=[AnswerOption.from_dict(o) for o in data.get("options", [])],
81 )
82 # restore FlexoEntity core fields
83 if "flexo_id" in data:
84 obj.flexo_id = FlexOID.to_dict(data["flexo_id"])
85 return obj
86
87@pytest.fixture
88def sample_domain():
89 domain_id = "PY_ARITHM"
90 flexo_id = FlexOID.safe_generate(domain_id=domain_id,
91 entity_type=EntityType.DOMAIN.value,
92 state=EntityState.DRAFT.value, text=domain_id)
93 return Domain(flexo_id=flexo_id, fullname="PYTHON_ARITHMETIC",
94 description="ALL ABOUT ARITHMETIC IN PYTHON")
95
96@pytest.fixture
97def sample_question(sample_domain):
98 flexo_id = FlexOID.safe_generate(domain_id=sample_domain.domain_id,
99 entity_type=EntityType.ITEM.value,
100 state=EntityState.DRAFT.value,
101 text="What is 2 + 2")
102 q = SingleChoiceQuestion(flexo_id=flexo_id, text="What is 2 + 2?",
103 options=[])
104 q._update_fingerprint()
105 return q
Note: See TracBrowser for help on using the repository browser.