"""
Las reglas del progreso del recorrido, sin pasar por ninguna puerta.

Omitir, retomar y fechar un paso cumplido son decisiones de
`apps.onboarding.services`: no dependen de si quien pidió la operación entró por
la pantalla o por la API. Estaban comprobadas dos veces —una por cada puerta— y
ninguna de las dos tocaba el servicio, así que cambiar la regla obligaba a
corregir dos archivos y ninguno era donde vive la decisión.

Lo que queda en las puertas es lo suyo: que omitir redirija al tablero y no al
listado, que la respuesta traiga el JSON acordado. Eso sí cambia según por dónde
se entre.
"""

import pytest

from apps.onboarding import services
from apps.onboarding.models import OnboardingProgress
from tests.factories import TEST_KEY, create_account

pytestmark = pytest.mark.django_db


@pytest.fixture
def account():
    return create_account()


def test_dismissing_twice_preserves_the_first_date(account):
    """
    La fecha dice cuándo se eligió salir, y esa elección se hizo una sola vez.

    Reescribirla en cada intento haría que cualquier segunda llamada —un botón
    apretado dos veces, un reintento— corriera la fecha hacia adelante sin que
    nadie haya vuelto a decidir nada.
    """
    first = services.dismiss(account)['dismissed_at']

    assert services.dismiss(account)['dismissed_at'] == first


def test_dismissing_only_reaches_whoever_asked_for_it(account):
    """No hay identificador de cuenta en la operación, y por eso mismo se comprueba."""
    neighbor = create_account(email='vecina@ejemplo.test')

    services.dismiss(account)

    assert not OnboardingProgress.objects.filter(account=neighbor).exists()


def test_verifying_after_dismissing_puts_the_tour_back(account):
    """
    Retomar borra la marca de omitido.

    Conservarla mantendría para siempre el aviso que invita a retomar algo que ya
    se retomó (FR-018).
    """
    services.dismiss(account)

    resumed = services.verify(account, 'GOOGLE_PROJECT', {'project_id': TEST_KEY['project_id']})

    assert resumed['is_dismissed'] is False
    assert resumed['dismissed_at'] is None
    assert services.should_offer(account) is True


def test_a_completed_step_carries_the_date_it_was_checked(account):
    """Un paso cumplido sin fecha no dice cuándo lo comprobamos, que es la mitad del dato."""
    services.verify(account, 'GOOGLE_PROJECT', {'project_id': TEST_KEY['project_id']})

    checked = services.state(account)['steps']

    assert next(one for one in checked if one['code'] == 'GOOGLE_PROJECT')['completed_at']
