# Path: shared_schema_tenants/models.py
# class Tenant(TimeStampedModel):
#     name = models.CharField(max_length=255)
#     slug = models.CharField(max_length=255, primary_key=True)
# 
#     if 'postgresql' in django_settings.DATABASES['default']['ENGINE']:
#         from django.contrib.postgres.fields import JSONField
#         extra_data = JSONField(blank=True, null=True,
#                                default=get_setting('DEFAULT_TENANT_EXTRA_DATA'))
#         settings = JSONField(blank=True, null=True,
#                              default=get_setting('DEFAULT_TENANT_SETTINGS'))
#     else:
#         _extra_data = models.TextField(blank=True, null=True,
#                                        validators=[validate_json],
#                                        default=json.dumps(get_setting('DEFAULT_TENANT_EXTRA_DATA')))
#         _settings = models.TextField(blank=True, null=True,
#                                      validators=[validate_json],
#                                      default=json.dumps(get_setting('DEFAULT_TENANT_SETTINGS')))
# 
#         @property
#         def extra_data(self):
#             import json
#             return json.loads(self._extra_data)
# 
#         @extra_data.setter
#         def extra_data(self, value):
#             import json
#             self._extra_data = json.dumps(value)
# 
#         @property
#         def settings(self):
#             import json
#             return json.loads(self._settings)
# 
#         @settings.setter
#         def settings(self, value):
#             import json
#             self._settings = json.dumps(value)
# 
#     def __str__(self):
#         return self.name
# 
# class TenantSite(TimeStampedModel, SingleTenantModelMixin):
#     tenant = models.ForeignKey('Tenant', related_name="tenant_sites")
#     site = models.OneToOneField(Site, related_name="tenant_site")
# 
#     def __str__(self):
#         return '%s - %s' % (self.tenant.name, self.site.domain)
# 
# class TenantRelationship(TimeStampedModel, SingleTenantModelMixin):
#     tenant = models.ForeignKey('Tenant', related_name="relationships")
#     user = models.ForeignKey(django_settings.AUTH_USER_MODEL, related_name="relationships")
#     groups = models.ManyToManyField('auth.Group',
#                                     related_name="user_tenant_groups",
#                                     blank=True)
#     permissions = models.ManyToManyField('auth.Permission',
#                                          related_name="user_tenant_permissions",
#                                          blank=True)
# 
#     def __str__(self):
#         groups_str = ', '.join([g.name for g in self.groups.all()])
#         return '%s - %s (%s)' % (str(self.user), str(self.tenant), groups_str)
# 
#     class Meta:
#         unique_together = [('user', 'tenant')]
# 
# Path: shared_schema_tenants/middleware.py
# class TenantMiddleware(object):
#     _threadmap = {}
# 
#     def __init__(self, get_response):
#         self.get_response = get_response
#         # One-time configuration and initialization.
# 
#     @classmethod
#     def get_current_tenant(cls):
#         try:
#             return cls._threadmap[threading.get_ident()]
#         except KeyError:
#             return None
# 
#     @classmethod
#     def set_tenant(cls, tenant_slug):
#         cls._threadmap[threading.get_ident()] = SimpleLazyObject(
#             lambda: Tenant.objects.filter(slug=tenant_slug).first())
# 
#     @classmethod
#     def clear_tenant(cls):
#         del cls._threadmap[threading.get_ident()]
# 
#     def process_request(self, request):
#         request.tenant = SimpleLazyObject(lambda: get_tenant(request))
#         self._threadmap[threading.get_ident()] = request.tenant
# 
#         return request
# 
#     def process_exception(self, request, exception):
#         try:
#             del self._threadmap[threading.get_ident()]
#         except KeyError:
#             pass
# 
#     def process_response(self, request, response):
#         try:
#             del self._threadmap[threading.get_ident()]
#         except KeyError:
#             pass
#         return response
# 
#     def __call__(self, request):
#         # Code to be executed for each request before
#         # the view (and later middleware) are called.
#         request = self.process_request(request)
#         response = self.get_response(request)
#         return self.process_response(request, response)


from django.test import TestCase
from django.contrib.sites.models import Site
from django.contrib.auth.models import User
from shared_schema_tenants.models import Tenant, TenantSite, TenantRelationship
from shared_schema_tenants.middleware import TenantMiddleware
class TenantTests(TestCase):

    def test_create(self):
        tenant = Tenant(name='test', slug='test')
        tenant.save()
        TenantMiddleware.set_tenant(tenant)
        self.assertEqual(Tenant.objects.all().count(), 1)
        self.assertEqual(tenant.tenant_sites.all().count(), 0)


class TenantSiteTests(TestCase):

    def setUp(self):
        self.tenant = Tenant.objects.create(name='test', slug='test')
        self.site = Site.objects.create(name='test', domain="test.site.com")
        TenantMiddleware.set_tenant(self.tenant)

    def test_create(self):
        TenantSite.objects.create(tenant=self.tenant, site=self.site)
        self.assertEqual(TenantSite.objects.all().count(), 1)


class TenantRelationshipTests(TestCase):

    def setUp(self):
        self.tenant = Tenant.objects.create(name='test', slug='test')
        self.user = User.objects.create_user(
            first_name='test', last_name='test',
            username='test', email='test@sharedschematenants.com',
            password='test')

# Path: shared_schema_tenants/models.py
# class Tenant(TimeStampedModel):
#     name = models.CharField(max_length=255)
#     slug = models.CharField(max_length=255, primary_key=True)
# 
#     if 'postgresql' in django_settings.DATABASES['default']['ENGINE']:
#         from django.contrib.postgres.fields import JSONField
#         extra_data = JSONField(blank=True, null=True,
#                                default=get_setting('DEFAULT_TENANT_EXTRA_DATA'))
#         settings = JSONField(blank=True, null=True,
#                              default=get_setting('DEFAULT_TENANT_SETTINGS'))
#     else:
#         _extra_data = models.TextField(blank=True, null=True,
#                                        validators=[validate_json],
#                                        default=json.dumps(get_setting('DEFAULT_TENANT_EXTRA_DATA')))
#         _settings = models.TextField(blank=True, null=True,
#                                      validators=[validate_json],
#                                      default=json.dumps(get_setting('DEFAULT_TENANT_SETTINGS')))
# 
#         @property
#         def extra_data(self):
#             import json
#             return json.loads(self._extra_data)
# 
#         @extra_data.setter
#         def extra_data(self, value):
#             import json
#             self._extra_data = json.dumps(value)
# 
#         @property
#         def settings(self):
#             import json
#             return json.loads(self._settings)
# 
#         @settings.setter
#         def settings(self, value):
#             import json
#             self._settings = json.dumps(value)
# 
#     def __str__(self):
#         return self.name
# 
# class TenantSite(TimeStampedModel, SingleTenantModelMixin):
#     tenant = models.ForeignKey('Tenant', related_name="tenant_sites")
#     site = models.OneToOneField(Site, related_name="tenant_site")
# 
#     def __str__(self):
#         return '%s - %s' % (self.tenant.name, self.site.domain)
# 
# class TenantRelationship(TimeStampedModel, SingleTenantModelMixin):
#     tenant = models.ForeignKey('Tenant', related_name="relationships")
#     user = models.ForeignKey(django_settings.AUTH_USER_MODEL, related_name="relationships")
#     groups = models.ManyToManyField('auth.Group',
#                                     related_name="user_tenant_groups",
#                                     blank=True)
#     permissions = models.ManyToManyField('auth.Permission',
#                                          related_name="user_tenant_permissions",
#                                          blank=True)
# 
#     def __str__(self):
#         groups_str = ', '.join([g.name for g in self.groups.all()])
#         return '%s - %s (%s)' % (str(self.user), str(self.tenant), groups_str)
# 
#     class Meta:
#         unique_together = [('user', 'tenant')]
# 
# Path: shared_schema_tenants/middleware.py
# class TenantMiddleware(object):
#     _threadmap = {}
# 
#     def __init__(self, get_response):
#         self.get_response = get_response
#         # One-time configuration and initialization.
# 
#     @classmethod
#     def get_current_tenant(cls):
#         try:
#             return cls._threadmap[threading.get_ident()]
#         except KeyError:
#             return None
# 
#     @classmethod
#     def set_tenant(cls, tenant_slug):
#         cls._threadmap[threading.get_ident()] = SimpleLazyObject(
#             lambda: Tenant.objects.filter(slug=tenant_slug).first())
# 
#     @classmethod
#     def clear_tenant(cls):
#         del cls._threadmap[threading.get_ident()]
# 
#     def process_request(self, request):
#         request.tenant = SimpleLazyObject(lambda: get_tenant(request))
#         self._threadmap[threading.get_ident()] = request.tenant
# 
#         return request
# 
#     def process_exception(self, request, exception):
#         try:
#             del self._threadmap[threading.get_ident()]
#         except KeyError:
#             pass
# 
#     def process_response(self, request, response):
#         try:
#             del self._threadmap[threading.get_ident()]
#         except KeyError:
#             pass
#         return response
# 
#     def __call__(self, request):
#         # Code to be executed for each request before
#         # the view (and later middleware) are called.
#         request = self.process_request(request)
#         response = self.get_response(request)
#         return self.process_response(request, response)


# Path: shared_schema_tenants/tests/test_models.py
from django.test import TestCase
from django.contrib.sites.models import Site
from django.contrib.auth.models import User
from shared_schema_tenants.models import Tenant, TenantSite, TenantRelationship
from shared_schema_tenants.middleware import TenantMiddleware

class TenantTests(TestCase):

    def test_create(self):
        tenant = Tenant(name='test', slug='test')
        tenant.save()
        TenantMiddleware.set_tenant(tenant)
        self.assertEqual(Tenant.objects.all().count(), 1)
        self.assertEqual(tenant.tenant_sites.all().count(), 0)


class TenantSiteTests(TestCase):

    def setUp(self):
        self.tenant = Tenant.objects.create(name='test', slug='test')
        self.site = Site.objects.create(name='test', domain="test.site.com")
        TenantMiddleware.set_tenant(self.tenant)

    def test_create(self):
        TenantSite.objects.create(tenant=self.tenant, site=self.site)
        self.assertEqual(TenantSite.objects.all().count(), 1)


class TenantRelationshipTests(TestCase):

    def setUp(self):
        self.tenant = Tenant.objects.create(name='test', slug='test')
        self.user = User.objects.create_user(
            first_name='test', last_name='test',
            username='test', email='test@sharedschematenants.com',
            password='test')

        TenantMiddleware.set_tenant(self.tenant)