import pytest

from django_lumen.models import DiagramPreferences, _default_excluded_apps


# ── _default_excluded_apps ────────────────────────────────────────────────────

class TestDefaultExcludedApps:
    def test_returns_list(self):
        assert isinstance(_default_excluded_apps(), list)

    def test_contains_all_system_apps(self):
        excluded = _default_excluded_apps()
        for app in ('contenttypes', 'sessions', 'admin', 'auth', 'django_lumen'):
            assert app in excluded

    def test_returns_new_list_each_call(self):
        # Mutable default — each call must return an independent list
        a = _default_excluded_apps()
        b = _default_excluded_apps()
        a.append('extra')
        assert 'extra' not in b


# ── DiagramPreferences ────────────────────────────────────────────────────────

@pytest.mark.django_db
class TestDiagramPreferences:
    def test_str_includes_username(self, django_user_model):
        user = django_user_model.objects.create_user(username='alice', password='pw')
        prefs = DiagramPreferences.objects.create(user=user)
        assert 'alice' in str(prefs)

    def test_default_routing_style_is_curved(self, django_user_model):
        user = django_user_model.objects.create_user(username='bob', password='pw')
        prefs = DiagramPreferences.objects.create(user=user)
        assert prefs.routing_style == 'curved'

    def test_default_excluded_apps_contains_system_apps(self, django_user_model):
        user = django_user_model.objects.create_user(username='carol', password='pw')
        prefs = DiagramPreferences.objects.create(user=user)
        for app in ('auth', 'admin', 'sessions', 'contenttypes', 'django_lumen'):
            assert app in prefs.excluded_apps

    def test_default_selected_apps_is_empty(self, django_user_model):
        user = django_user_model.objects.create_user(username='dave', password='pw')
        prefs = DiagramPreferences.objects.create(user=user)
        assert prefs.selected_apps == []

    def test_one_to_one_prevents_duplicate(self, django_user_model):
        from django.db import IntegrityError
        user = django_user_model.objects.create_user(username='eve', password='pw')
        DiagramPreferences.objects.create(user=user)
        with pytest.raises(IntegrityError):
            DiagramPreferences.objects.create(user=user)

    def test_custom_routing_style_persists(self, django_user_model):
        user = django_user_model.objects.create_user(username='frank', password='pw')
        DiagramPreferences.objects.create(user=user, routing_style='orthogonal')
        prefs = DiagramPreferences.objects.get(user=user)
        assert prefs.routing_style == 'orthogonal'

    def test_selected_apps_persists(self, django_user_model):
        user = django_user_model.objects.create_user(username='grace', password='pw')
        DiagramPreferences.objects.create(user=user, selected_apps=['myapp', 'otherapp'])
        prefs = DiagramPreferences.objects.get(user=user)
        assert prefs.selected_apps == ['myapp', 'otherapp']

    def test_excluded_apps_persists(self, django_user_model):
        user = django_user_model.objects.create_user(username='heidi', password='pw')
        DiagramPreferences.objects.create(user=user, excluded_apps=['auth'])
        prefs = DiagramPreferences.objects.get(user=user)
        assert prefs.excluded_apps == ['auth']

    def test_cascade_delete_with_user(self, django_user_model):
        user = django_user_model.objects.create_user(username='ivan', password='pw')
        DiagramPreferences.objects.create(user=user)
        assert DiagramPreferences.objects.filter(user=user).exists()
        user.delete()
        assert not DiagramPreferences.objects.filter(user__username='ivan').exists()
