Files
031-flash-card/tests/unit/test_flash_card_view_model.py
Tirsvad b3c5116110 MIL-006: Spoken Malay word
Review record RC-028 (Go, autonomous mode, not independent).

Task: MIL-006#1
Task: MIL-006#2
Task: MIL-006#3
Task: MIL-006#4
Task: MIL-006#5
2026-10-14 22:39:36 +08:00

156 lines
4.8 KiB
Python

"""Tests of the flash card view model over a real session and in-memory deck."""
from collections.abc import Sequence
from flash_card.application.use_cases.study_session import StudySession
from flash_card.constants import FINISHED_MESSAGE
from flash_card.domain.entities.card import Card
from flash_card.domain.entities.deck import Deck
from flash_card.domain.value_objects.language_pair import LanguagePair
from flash_card.presentation.features.flash_card.flash_card_view_model import (
FlashCardViewModel,
Side,
)
A = Card("aku", "mig")
B = Card("kau", "du")
def _first(cards: Sequence[Card]) -> Card:
return cards[0]
class _RecordingProgress:
def __init__(self) -> None:
self.saved: list[tuple[Card, ...]] = []
def load(self) -> Deck | None:
return None
def save(self, deck: Deck) -> None:
self.saved.append(deck.cards)
class _SilentSpeech:
def speak(self, text: str, language_code: str) -> None:
return None
def _session(
code: str, *cards: Card, progress: _RecordingProgress | None = None
) -> StudySession:
store = _RecordingProgress() if progress is None else progress
return StudySession(
Deck(LanguagePair(code, "da"), cards), _first, store, _SilentSpeech()
)
def test_view_model_draws_first_card_on_construction() -> None:
view_model = FlashCardViewModel(_session("ms", A, B))
assert view_model.text == "aku"
assert view_model.language_name == "Malay"
assert not view_model.is_finished
def test_next_card_shows_next_card() -> None:
view_model = FlashCardViewModel(_session("ms", A, B))
view_model.next_card()
assert view_model.text == "kau"
def test_language_name_shows_unknown_code_in_upper_case() -> None:
view_model = FlashCardViewModel(_session("xx", A))
assert view_model.language_name == "XX"
def test_language_name_uses_given_names() -> None:
view_model = FlashCardViewModel(_session("ms", A), {"ms": "Melayu"})
assert view_model.language_name == "Melayu"
def test_view_model_shows_finished_message_when_no_card_is_left() -> None:
view_model = FlashCardViewModel(_session("ms"))
assert view_model.is_finished
assert view_model.language_name == ""
assert view_model.text == FINISHED_MESSAGE
def test_view_model_starts_on_front_side() -> None:
view_model = FlashCardViewModel(_session("ms", A))
assert view_model.side is Side.FRONT
def test_flip_card_shows_back_language_and_translation() -> None:
view_model = FlashCardViewModel(_session("ms", A))
view_model.flip_card()
assert view_model.side is Side.BACK
assert view_model.language_name == "Danish"
assert view_model.text == "mig"
def test_flip_card_twice_keeps_back_side() -> None:
view_model = FlashCardViewModel(_session("ms", A))
view_model.flip_card()
view_model.flip_card()
assert view_model.side is Side.BACK
assert view_model.text == "mig"
def test_flip_card_does_nothing_when_finished() -> None:
view_model = FlashCardViewModel(_session("ms"))
view_model.flip_card()
assert view_model.side is Side.FRONT
assert view_model.language_name == ""
assert view_model.text == FINISHED_MESSAGE
def test_next_card_resets_side_to_front() -> None:
view_model = FlashCardViewModel(_session("ms", A, B))
view_model.flip_card()
view_model.next_card()
assert view_model.side is Side.FRONT
assert view_model.language_name == "Malay"
assert view_model.text == "kau"
def test_is_known_saves_remaining_and_shows_next_front() -> None:
progress = _RecordingProgress()
view_model = FlashCardViewModel(_session("ms", A, B, progress=progress))
view_model.flip_card()
view_model.is_known()
assert progress.saved == [(B,)]
assert view_model.side is Side.FRONT
assert view_model.text == "kau"
assert not view_model.is_finished
def test_is_known_on_last_card_finishes() -> None:
progress = _RecordingProgress()
view_model = FlashCardViewModel(_session("ms", A, progress=progress))
view_model.is_known()
assert view_model.is_finished
assert view_model.text == FINISHED_MESSAGE
assert progress.saved == [()]
def test_is_known_does_nothing_when_finished() -> None:
progress = _RecordingProgress()
view_model = FlashCardViewModel(_session("ms", progress=progress))
view_model.is_known()
assert view_model.is_finished
assert progress.saved == []
def test_next_card_does_nothing_when_finished() -> None:
view_model = FlashCardViewModel(_session("ms"))
view_model.next_card()
assert view_model.is_finished
assert view_model.text == FINISHED_MESSAGE
def test_next_card_never_saves() -> None:
progress = _RecordingProgress()
view_model = FlashCardViewModel(_session("ms", A, B, progress=progress))
view_model.next_card()
assert progress.saved == []