"""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) 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) 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 == []