Changeset 8aa20c7 in flexoentity for tests/conftest.py


Ignore:
Timestamp:
11/01/25 15:51:10 (2 months ago)
Author:
Enrico Schwass <ennoausberlin@…>
Branches:
master
Children:
5c72356
Parents:
ca39274
Message:

full refactoring of FlexOID

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tests/conftest.py

    rca39274 r8aa20c7  
    1 # tests/conftest.py
    2 
     1# tests/stubs/single_choice_question.py
    32import pytest
    4 import json
     3from datetime import datetime
     4from dataclasses import dataclass, field
     5from typing import List
    56from flexoentity import FlexoEntity, EntityType, EntityState, Domain
    67
    7 import pytest
    8 import json
    9 from flexoentity import EntityType, EntityState, Domain
    10 from builder.questions import RadioQuestion, AnswerOption  # adjust path if different
    11 from builder.media_items import NullMediaItem  # adjust import if needed
     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
    1216
    1317
    14 @pytest.fixture(scope="session")
    15 def domain():
    16     """Provide a reusable domain for all entity tests."""
    17     return Domain(
    18         domain="SIG",
    19         etype=EntityType.DOMAIN,
    20         state=EntityState.DRAFT,
    21         fullname="Signal Corps",
    22         description="Questions related to communications and signaling systems.",
    23         classification="RESTRICTED",
    24         owner="test-suite"
    25     )
     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        )
    2634
    2735
    28 @pytest.fixture
    29 def radio_question(domain):
    30     """Return a simple RadioQuestion entity for testing FlexoEntity logic."""
    31     q = RadioQuestion(
    32         domain=domain,
    33         etype=EntityType.QUESTION,
    34         state=EntityState.DRAFT,
    35         text="Which frequency band is used for shortwave communication?",
    36         options=[
    37             AnswerOption(id="opt1", text="HF (3–30 MHz)", points=1),
    38             AnswerOption(id="opt2", text="VHF (30–300 MHz)", points=0),
    39             AnswerOption(id="opt3", text="UHF (300–3000 MHz)", points=0),
    40         ]
    41     )
    42     return q
     36@dataclass
     37class SingleChoiceQuestion(FlexoEntity):
     38    """A minimal stub to test FlexoEntity integration."""
     39    text: str = ""
     40    options: List[AnswerOption] = field(default_factory=list)
    4341
    4442
    45 @pytest.fixture
    46 def serialized_question(radio_question):
    47     """Provide the serialized JSON form for roundtrip tests."""
    48     return radio_question.to_json()
     43    @classmethod
     44    def default(cls):
     45        return cls(domain=Domain(domain="GEN",
     46                                 entity_type=EntityType.DOMAIN,
     47                                 state=EntityState.DRAFT),
     48                   state=EntityState.DRAFT, entity_type=EntityType.ITEM)
    4949
     50    def to_dict(self):
     51        base = super().to_dict()
     52        base.update({
     53            "text": self.text,
     54            "options": [opt.to_dict() for opt in self.options],
     55        })
     56        return base
     57
     58    @property
     59    def text_seed(self) -> str:
     60        """Include answer options (and points) for deterministic ID generation."""
     61
     62        joined = "|".join(
     63            f"{opt.text.strip()}:{opt.points}"
     64            for opt in sorted(self.options, key=lambda o: o.text.strip().lower())
     65        )
     66        return f"{self.text}{joined}"
     67
     68    @classmethod
     69    def from_dict(cls, data):
     70        obj = cls(
     71            text=data.get("text", ""),
     72            options=[AnswerOption.from_dict(o) for o in data.get("options", [])],
     73        )
     74        # restore FlexoEntity core fields
     75        obj.domain = data.get("domain")
     76        obj.entity_type = EntityType[data.get("etype")] if "etype" in data else EntityType.ITEM
     77        obj.state = EntityState[data.get("state")] if "state" in data else EntityState.DRAFT
     78        if "flexo_id" in data:
     79            from flexoentity import FlexOID
     80            obj.flexo_id = FlexOID.parsed(data["flexo_id"])
     81        return obj
    5082
    5183@pytest.fixture
    52 def deserialized_question(serialized_question):
    53     """Recreate a question from JSON for consistency tests."""
    54     return RadioQuestion.from_json(serialized_question)
    55 
     84def domain():
     85    return Domain.default()
    5686
    5787@pytest.fixture
    58 def null_media():
    59     """Provide a default NullMediaItem instance for media tests."""
    60     return NullMediaItem(
    61         domain=domain,
    62         etype=EntityType.MEDIA,
    63         state=EntityState.DRAFT
    64     )
     88def sample_question():
     89    return SingleChoiceQuestion(domain=Domain.default(),
     90                               text="What is 2 + 2?",
     91                               options=[],
     92                               entity_type=EntityType.ITEM,
     93                               state=EntityState.DRAFT)
Note: See TracChangeset for help on using the changeset viewer.