from django.http.response import HttpResponseRedirectBase
from django.shortcuts import HttpResponse
from django.test import TestCase
from django.contrib.auth import get_user_model
from django.test.client import RequestFactory
from django.conf import settings

from accrete.decorator import tenant_required
from accrete.models import Tenant, Member

User = get_user_model()


def group_missing_action(request, tenant_groups, member_groups):
    return HttpResponse('group missing action')


@tenant_required()
def dummy(request):
    return True


@tenant_required(member_groups=['test'], group_missing_action=group_missing_action)
def dummy_group(request):
    return True


class DecoratorTestCase(TestCase):

    def setUp(self):
        self.factory = RequestFactory()
        self.user = User(email='user@accrete.test', username='Test User', is_active=True)
        self.user.save()
        self.tenant = Tenant(name='Test Tenant')
        self.tenant.save()

    def test_tenant_not_set(self):
        request = self.factory.get('/')
        request.user = self.user
        request.tenant = None
        response = dummy(request)
        self.assertTrue(isinstance(response, HttpResponseRedirectBase))
        self.assertTrue(response.url.startswith(settings.ACCRETE_TENANT_NOT_SET_URL))

    def test_group_missing(self):
        member = Member(tenant=self.tenant, user=self.user)
        member.save()
        request = self.factory.get('/')
        request.user = self.user
        request.tenant = self.tenant
        request.member = member
        result = dummy_group(request)
        self.assertEqual(result.text, 'group missing action')

    def test_staff_bypass(self):
        user = User(
            email='staff@test.com',
            username='Staff User',
            is_active=True,
            is_staff=True
        )
        user.save()
        request = self.factory.get('/')
        request.tenant = self.tenant
        request.member = None
        request.user = user
        result = dummy_group(request)
        self.assertEqual(result, True)
