from django.test import TestCase

from django_orghierarchy.forms import (
    AffiliatedOrganizationForm,
    OrganizationForm,
    SubOrganizationForm,
)
from django_orghierarchy.models import Organization

from .factories import DataSourceFactory, OrganizationClassFactory, OrganizationFactory


class TestOrganizationForm(TestCase):
    def setUp(self):
        self.organization = OrganizationFactory()
        self.data_source = DataSourceFactory(user_editable_organizations=True)

    def test_init_without_instance(self):
        form = OrganizationForm()
        self.assertQuerySetEqual(form.fields["parent"].queryset, [self.organization])

    def test_init_with_instance(self):
        form = OrganizationForm(instance=self.organization)
        self.assertQuerySetEqual(form.fields["parent"].queryset, [])

    def test_replaced_by_field_queryset_exclude_already_replaced(self):
        OrganizationFactory(replaced_by=self.organization)
        organization_2 = OrganizationFactory()

        form = OrganizationForm()
        queryset = form.fields["replaced_by"].queryset
        self.assertQuerySetEqual(
            queryset, [self.organization, organization_2], ordered=False
        )

        form = OrganizationForm(instance=organization_2)
        queryset = form.fields["replaced_by"].queryset
        self.assertQuerySetEqual(queryset, [self.organization])

    def test_clean(self):
        form_data = {
            "data_source": self.data_source.id,
            "origin_id": "abc",
            "classification": self.organization.classification_id,
            "name": "test org",
            "internal_type": Organization.AFFILIATED,
            "parent": "",
        }
        form = OrganizationForm(form_data)
        self.assertFalse(form.is_valid())

        form_data["parent"] = self.organization.id
        form = OrganizationForm(form_data)
        self.assertTrue(form.is_valid())


class TestSubOrganizationForm(TestCase):
    def setUp(self):
        self.data_source = DataSourceFactory(user_editable_organizations=True)
        self.organization_class = OrganizationClassFactory()

    def test__init__(self):
        form = SubOrganizationForm()
        self.assertEqual(form.initial["internal_type"], Organization.NORMAL)

        form = SubOrganizationForm(initial={"internal_type": Organization.AFFILIATED})
        self.assertEqual(form.initial["internal_type"], Organization.NORMAL)

    def test_clean_internal_type(self):
        form_data = {
            "internal_type": Organization.NORMAL,
            "data_source": self.data_source.id,
            "origin_id": "sub-org",
            "classification": self.organization_class.id,
            "name": "sub organization",
        }
        form = SubOrganizationForm(form_data)
        self.assertTrue(form.is_valid())
        self.assertEqual(form.cleaned_data["internal_type"], Organization.NORMAL)

        form_data["internal_type"] = Organization.AFFILIATED
        form = SubOrganizationForm(form_data)
        self.assertTrue(form.is_valid())
        self.assertEqual(form.cleaned_data["internal_type"], Organization.NORMAL)


class TestAffiliatedOrganizationForm(TestCase):
    def setUp(self):
        self.data_source = DataSourceFactory(user_editable_organizations=True)
        self.organization_class = OrganizationClassFactory()

    def test__init__(self):
        form = AffiliatedOrganizationForm()
        self.assertEqual(form.initial["internal_type"], Organization.AFFILIATED)

        form = AffiliatedOrganizationForm(
            initial={"internal_type": Organization.NORMAL}
        )
        self.assertEqual(form.initial["internal_type"], Organization.AFFILIATED)

    def test_clean_internal_type(self):
        form_data = {
            "internal_type": Organization.NORMAL,
            "data_source": self.data_source.id,
            "origin_id": "sub-org",
            "classification": self.organization_class.id,
            "name": "sub organization",
        }
        form = AffiliatedOrganizationForm(form_data)
        self.assertTrue(form.is_valid())
        self.assertEqual(form.cleaned_data["internal_type"], Organization.AFFILIATED)

        form_data["internal_type"] = Organization.AFFILIATED
        form = AffiliatedOrganizationForm(form_data)
        self.assertTrue(form.is_valid())
        self.assertEqual(form.cleaned_data["internal_type"], Organization.AFFILIATED)
