source: flexoentity/tests/conftest.py@ 5c72356

Last change on this file since 5c72356 was 5c72356, checked in by Enrico Schwass <ennoausberlin@…>, 2 months ago

fix tests due to simplifying state and type

  • Property mode set to 100644
File size: 2.9 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 domain_code = (
48 self.domain.domain if isinstance(self.domain, Domain) else "GEN"
49 )
50 self.flexo_id = FlexOID.safe_generate(
51 domain=domain_code,
52 entity_type=EntityType.ITEM.value, # 'I'
53 estate=EntityState.DRAFT.value, # 'D'
54 text=self.text_seed or self.text,
55 version=1,
56 )
57
58 @classmethod
59 def default(cls):
60 return cls(domain=Domain(domain="GEN"))
61
62 def to_dict(self):
63 base = super().to_dict()
64 base.update({
65 "text": self.text,
66 "options": [opt.to_dict() for opt in self.options],
67 })
68 return base
69
70 @property
71 def text_seed(self) -> str:
72 """Include answer options (and points) for deterministic ID generation."""
73
74 joined = "|".join(
75 f"{opt.text.strip()}:{opt.points}"
76 for opt in sorted(self.options, key=lambda o: o.text.strip().lower())
77 )
78 return f"{self.text}{joined}"
79
80 @classmethod
81 def from_dict(cls, data):
82 obj = cls(domain=Domain(domain="GEN"),
83 text=data.get("text", ""),
84 options=[AnswerOption.from_dict(o) for o in data.get("options", [])],
85 )
86 # restore FlexoEntity core fields
87 obj.domain = data.get("domain")
88 if "flexo_id" in data:
89 obj.flexo_id = FlexOID.parsed(data["flexo_id"])
90 return obj
91
92@pytest.fixture
93def domain():
94 return Domain.default()
95
96@pytest.fixture
97def sample_question():
98 q = SingleChoiceQuestion(domain=Domain.default(),
99 text="What is 2 + 2?",
100 options=[])
101 q._update_fingerprint()
102 return q
Note: See TracBrowser for help on using the repository browser.