コード例 #1
0
    def test_auto_drop_schema_bulk_delete(self):
        """
        When bulk deleting tenants, it should also drop the schemas of
        tenants that have auto_drop_schema set to True.
        """
        Tenant.auto_drop_schema = True
        schemas = ['auto_drop_schema1', 'auto_drop_schema2']
        for schema in schemas:
            self.assertFalse(schema_exists(schema))
            tenant = Tenant(
                domain_url='%s.test.com' % schema,
                schema_name=schema
            )
            tenant.save(verbosity=BaseTestCase.get_verbosity())
            self.assertTrue(schema_exists(tenant.schema_name))

        # Force pending trigger events to be executed
        cursor = connection.cursor()
        cursor.execute('SET CONSTRAINTS ALL IMMEDIATE')

        # get a queryset of our 2 tenants and do a bulk delete
        Tenant.objects.filter(schema_name__in=schemas).delete()

        # verify that the schemas where deleted
        for schema in schemas:
            self.assertFalse(schema_exists(schema))

        Tenant.auto_drop_schema = False
コード例 #2
0
    def test_tenant_schema_is_created(self):
        """
        When saving a tenant, it's schema should be created.
        """
        tenant = Tenant(domain_url='something.test.com', schema_name='test')
        tenant.save()

        self.assertTrue(schema_exists(tenant.schema_name))
コード例 #3
0
 def  test_throw_exception_if_db_not_specified(self):
     """
     When saving a tenant without 'using' kwarg of save method throw
     MultiDBError 
     """
     tenant = Tenant(domain_url='something.test.com', schema_name='test')
     try:
         tenant.save(
             verbosity=BaseTestCase.get_verbosity())
     except Exception as e:
         self.assertTrue(isinstance(e, MultipleDBError))
コード例 #4
0
    def test_switching_tenant_without_previous_tenant(self):
        tenant = Tenant(domain_url='something.test.com', schema_name='test')
        tenant.save()

        connection.tenant = None
        with tenant_context(tenant):
            DummyModel(name="No exception please").save()

        connection.tenant = None
        with schema_context(tenant.schema_name):
            DummyModel(name="Survived it!").save()
コード例 #5
0
    def setUp(self):
        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain,
                                    schema_name='public')
        self.public_tenant.save()

        connection.set_schema_to_public()
コード例 #6
0
    def test_switching_tenant_without_previous_tenant(self):
        tenant = Tenant(domain_url="something.test.com", schema_name="test")
        tenant.save(verbosity=BaseTestCase.get_verbosity())

        connection.tenant = None
        with tenant_context(tenant):
            DummyModel(name="No exception please").save()

        connection.tenant = None
        with schema_context(tenant.schema_name):
            DummyModel(name="Survived it!").save()
コード例 #7
0
class RoutesTestCase(BaseTestCase):
    @classmethod
    def setUpClass(cls):
        super(RoutesTestCase, cls).setUpClass()
        settings.SHARED_APPS = ('tenant_schemas', )
        settings.TENANT_APPS = (
            'dts_test_app',
            'django.contrib.contenttypes',
            'django.contrib.auth',
        )
        settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
        cls.sync_shared()
        cls.public_tenant = Tenant(domain_url='test.com',
                                   schema_name=get_public_schema_name())
        cls.public_tenant.save(verbosity=BaseTestCase.get_verbosity())

    def setUp(self):
        super(RoutesTestCase, self).setUp()
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save(verbosity=BaseTestCase.get_verbosity())

    def test_tenant_routing(self):
        """
        Request path should not be altered.
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.tenant)

    def test_public_schema_routing(self):
        """
        Request path should not be altered.
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.public_tenant.domain_url)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.public_tenant)
コード例 #8
0
class RoutesTestCase(TransactionTestCase):
    @classmethod
    def setUpClass(cls):
        settings.TENANT_APPS = ('tenant_schemas', 'django.contrib.contenttypes', 'django.contrib.auth', )

    def setUp(self):
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'
        settings.PUBLIC_SCHEMA_URL_TOKEN = '/public'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain, schema_name='public')
        self.public_tenant.save()

        # add a test tenant
        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save()

    def tearDown(self):
        Tenant.objects.all().delete()

    def test_tenant_routing(self):
        """
        request path should not be altered
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/', HTTP_HOST=self.tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.tenant)

    def test_public_schema_routing(self):
        """
        request path should get prepended with PUBLIC_SCHEMA_URL_TOKEN
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/', HTTP_HOST=self.public_tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, settings.PUBLIC_SCHEMA_URL_TOKEN + request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.public_tenant)
コード例 #9
0
class RoutesTestCase(TestCase):
    def setUp(self):
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'
        settings.PUBLIC_SCHEMA_URL_TOKEN = '/public'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain,
                                    schema_name='public')
        self.public_tenant.save()

        # add a test tenant
        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save()

    def tearDown(self):
        Tenant.objects.all().delete()

    def test_tenant_routing(self):
        """
        request path should not be altered
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.tenant)

    def test_public_schema_routing(self):
        """
        request path should get prepended with PUBLIC_SCHEMA_URL_TOKEN
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.public_tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info,
                          settings.PUBLIC_SCHEMA_URL_TOKEN + request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.public_tenant)
コード例 #10
0
    def setUp(self):
        super(RoutesTestCase, self).setUp()
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()
        self.dtm = DefaultTenantMiddleware()

        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save(verbosity=BaseTestCase.get_verbosity())

        self.non_existent_domain = 'no-tenant.test.com'
        self.non_existent_tenant = Tenant(domain_url=self.non_existent_domain, schema_name='no-tenant')

        self.url = '/any/path/'
コード例 #11
0
    def test_switching_search_path(self):
        dummies_tenant1_count, dummies_tenant2_count = 0, 0

        tenant1 = Tenant(domain_url='test.com', schema_name='tenant1')
        tenant1.save()

        connection.set_schema_to_public()
        tenant2 = Tenant(domain_url='example.com', schema_name='tenant2')
        tenant2.save()

        # go to tenant1's path
        connection.set_tenant(tenant1)

        # add some data
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()
        dummies_tenant1_count = DummyModel.objects.count()

        # switch temporarily to tenant2's path
        with tenant_context(tenant2):
            # add some data
            DummyModel(name="Man,").save()
            DummyModel(name="testing").save()
            DummyModel(name="is great!").save()
            dummies_tenant2_count = DummyModel.objects.count()

        # we should be back to tenant1's path, test what we have
        self.assertEqual(DummyModel.objects.count(), dummies_tenant1_count)

        # switch back to tenant2's path
        with tenant_context(tenant2):
            self.assertEqual(DummyModel.objects.count(), dummies_tenant2_count)
コード例 #12
0
    def test_switching_search_path(self):
        tenant1 = Tenant(domain_url='something.test.com',
                         schema_name='tenant1')
        tenant1.save(verbosity=BaseTestCase.get_verbosity())

        connection.set_schema_to_public()
        tenant2 = Tenant(domain_url='example.com', schema_name='tenant2')
        tenant2.save(verbosity=BaseTestCase.get_verbosity())

        # go to tenant1's path
        connection.set_tenant(tenant1)

        # add some data, 2 DummyModels for tenant1
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()

        # switch temporarily to tenant2's path
        with tenant_context(tenant2):
            # add some data, 3 DummyModels for tenant2
            DummyModel(name="Man,").save()
            DummyModel(name="testing").save()
            DummyModel(name="is great!").save()

        # we should be back to tenant1's path, test what we have
        self.assertEqual(2, DummyModel.objects.count())

        # switch back to tenant2's path
        with tenant_context(tenant2):
            self.assertEqual(3, DummyModel.objects.count())
コード例 #13
0
class RoutesTestCase(BaseTestCase):
    @classmethod
    def setUpClass(cls):
        super(RoutesTestCase, cls).setUpClass()
        settings.SHARED_APPS = ('tenant_schemas', )
        settings.TENANT_APPS = ('dts_test_app',
                                'django.contrib.contenttypes',
                                'django.contrib.auth', )
        settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
        cls.sync_shared()
        cls.public_tenant = Tenant(domain_url='test.com', schema_name=get_public_schema_name())
        cls.public_tenant.save(verbosity=BaseTestCase.get_verbosity())

    def setUp(self):
        super(RoutesTestCase, self).setUp()
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save(verbosity=BaseTestCase.get_verbosity())

    def test_tenant_routing(self):
        """
        Request path should not be altered.
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.tenant)

    def test_public_schema_routing(self):
        """
        Request path should not be altered.
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.public_tenant.domain_url)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.public_tenant)
コード例 #14
0
ファイル: tests.py プロジェクト: bufke/tenant-schemas-celery
    def setUp(self):
        super(CeleryTasksTests, self).setUp()
        self.tenant1 = Tenant(domain_url='test1', schema_name='test1')
        self.tenant1.save()

        self.tenant2 = Tenant(domain_url='test2', schema_name='test2')
        self.tenant2.save()

        connection.set_tenant(self.tenant1)
        self.dummy1 = DummyModel.objects.create(name='test1')

        connection.set_tenant(self.tenant2)
        self.dummy2 = DummyModel.objects.create(name='test2')

        connection.set_schema_to_public()
コード例 #15
0
    def setUp(self):
        super(CeleryTasksTests, self).setUp()
        self.tenant1 = Tenant(domain_url='test1', schema_name='test1')
        self.tenant1.save()

        self.tenant2 = Tenant(domain_url='test2', schema_name='test2')
        self.tenant2.save()

        connection.set_tenant(self.tenant1)
        self.dummy1 = DummyModel.objects.create(name='test1')

        connection.set_tenant(self.tenant2)
        self.dummy2 = DummyModel.objects.create(name='test2')

        connection.set_schema_to_public()
コード例 #16
0
    def test_command(self):
        """
        Tests that tenant_command is capable of wrapping commands
        and its parameters.
        """
        settings.SHARED_APPS = (
            "tenant_schemas",
            "django.contrib.contenttypes",
        )
        settings.TENANT_APPS = ()
        settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
        self.sync_shared()
        Tenant(
            domain_url="localhost",
            schema_name="public").save(verbosity=BaseTestCase.get_verbosity())

        out = StringIO()
        tenant_command.Command().handle(
            "dumpdata",
            get_public_schema_name(),
            "tenant_schemas",
            natural_foreign=True,
            stdout=out,
        )
        self.assertJSONEqual(
            out.getvalue(),
            [{
                "fields": {
                    "domain_url": "localhost",
                    "schema_name": "public"
                },
                "model": "tenant_schemas.tenant",
                "pk": 1,
            }],
        )
コード例 #17
0
    def test_command(self):
        """
        Tests that tenant_command is capable of wrapping commands
        and its parameters.
        """
        settings.SHARED_APPS = (
            'tenant_schemas',
            'django.contrib.contenttypes',
        )
        settings.TENANT_APPS = ()
        settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
        self.sync_shared()
        Tenant(
            domain_url='localhost',
            schema_name='public').save(verbosity=BaseTestCase.get_verbosity())

        out = StringIO()
        call_command('tenant_command',
                     args=('dumpdata', 'tenant_schemas'),
                     natural_foreign=True,
                     schema_name=get_public_schema_name(),
                     stdout=out)
        self.assertEqual(
            json.loads(
                '[{"fields": {"domain_url": "localhost", "schema_name": "public"}, '
                '"model": "tenant_schemas.tenant", "pk": 1}]'),
            json.loads(out.getvalue()))
コード例 #18
0
ファイル: routes.py プロジェクト: rctay/django-tenant-schemas
class RoutesTestCase(TestCase):
    def setUp(self):
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'
        settings.TENANT_URL_TOKEN = '/tenant'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain, schema_name='public')
        self.public_tenant.save()

        # add a test tenant
        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save()

    def tearDown(self):
        Tenant.objects.all().delete()

    def test_tenant_routing(self):
        """
        request path should get prepended with TENANT_URL_TOKEN
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/', HTTP_HOST=self.tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, settings.TENANT_URL_TOKEN + request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.tenant)

    def test_public_schema_routing(self):
        """
        request path should not be altered, tenant should be the public one
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/', HTTP_HOST=self.public_tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.public_tenant)
コード例 #19
0
    def setUp(self):
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain,
                                    schema_name='public')
        self.public_tenant.save()

        # add a test tenant
        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save()
コード例 #20
0
    def setUp(self):
        super(RoutesTestCase, self).setUp()
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save()
コード例 #21
0
    def test_tenant_apps_does_not_sync_shared_apps(self):
        """
        Tests that if an app is in TENANT_APPS, it does not get synced to
        the public schema.
        """
        settings.SHARED_APPS = ('tenant_schemas',
                                'django.contrib.auth',
                                'django.contrib.contenttypes', )
        settings.TENANT_APPS = ('django.contrib.sessions', )  # 1 table
        settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
        self.sync_shared()
        tenant = Tenant(domain_url='arbitrary.test.com', schema_name='test')
        tenant.save()

        tenant_tables = self.get_tables_list_in_schema(tenant.schema_name)
        self.assertEqual(1+self.MIGRATION_TABLE_SIZE, len(tenant_tables))
        self.assertIn('django_session', tenant_tables)
コード例 #22
0
    def setUp(self):
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'
        settings.PUBLIC_SCHEMA_URL_TOKEN = '/public'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain, schema_name='public')
        self.public_tenant.save()

        # add a test tenant
        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save()
コード例 #23
0
 def setUpClass(cls):
     super(TenantDataAndSettingsTest, cls).setUpClass()
     settings.SHARED_APPS = ('tenant_schemas', )
     settings.TENANT_APPS = ('dts_test_app',
                             'django.contrib.contenttypes',
                             'django.contrib.auth', )
     settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
     cls.sync_shared()
     Tenant(domain_url='test.com', schema_name=get_public_schema_name()).save()
コード例 #24
0
    def test_auto_drop_schema(self):
        """
        When deleting a tenant with auto_drop_schema=True, it should delete
        the schema associated with the tenant.
        """
        self.assertFalse(schema_exists('auto_drop_tenant'))
        Tenant.auto_drop_schema = True
        tenant = Tenant(domain_url='something.test.com',
                        schema_name='auto_drop_tenant')
        tenant.save(verbosity=BaseTestCase.get_verbosity())
        self.assertTrue(schema_exists(tenant.schema_name))
        cursor = connection.cursor()

        # Force pending trigger events to be executed
        cursor.execute('SET CONSTRAINTS ALL IMMEDIATE')

        tenant.delete()
        self.assertFalse(schema_exists(tenant.schema_name))
        Tenant.auto_drop_schema = False
コード例 #25
0
    def test_tenant_apps_does_not_sync_shared_apps(self):
        """
        Tests that if an app is in TENANT_APPS, it does not get synced to
        the public schema.
        """
        settings.SHARED_APPS = (
            "tenant_schemas",
            "django.contrib.auth",
            "django.contrib.contenttypes",
        )
        settings.TENANT_APPS = ("django.contrib.sessions", )  # 1 table
        settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
        self.sync_shared()
        tenant = Tenant(domain_url="arbitrary.test.com", schema_name="test")
        tenant.save(verbosity=BaseTestCase.get_verbosity())

        tenant_tables = self.get_tables_list_in_schema(tenant.schema_name)
        self.assertEqual(1 + self.MIGRATION_TABLE_SIZE, len(tenant_tables))
        self.assertIn("django_session", tenant_tables)
コード例 #26
0
    def test_content_types_is_not_mandatory(self):
        """
        Tests that even if content types is in SHARED_APPS, it's
        not required in TENANT_APPS.
        """
        settings.SHARED_APPS = ('tenant_schemas',  # 2 tables
                                'django.contrib.contenttypes', )  # 1 table
        settings.TENANT_APPS = ('django.contrib.sessions', )  # 1 table
        settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
        self.sync_shared()
        tenant = Tenant(domain_url='something.test.com', schema_name='test')
        tenant.save()

        shared_tables = self.get_tables_list_in_schema(get_public_schema_name())
        tenant_tables = self.get_tables_list_in_schema(tenant.schema_name)
        self.assertEqual(2+1+self.MIGRATION_TABLE_SIZE, len(shared_tables))
        self.assertIn('django_session', tenant_tables)
        self.assertEqual(1+self.MIGRATION_TABLE_SIZE, len(tenant_tables))
        self.assertIn('django_session', tenant_tables)
コード例 #27
0
 def setUpClass(cls):
     super(RoutesTestCase, cls).setUpClass()
     settings.SHARED_APPS = ('tenant_schemas', )
     settings.TENANT_APPS = ('dts_test_app',
                             'django.contrib.contenttypes',
                             'django.contrib.auth', )
     settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
     cls.sync_shared()
     cls.public_tenant = Tenant(domain_url='test.com', schema_name=get_public_schema_name())
     cls.public_tenant.save(verbosity=BaseTestCase.get_verbosity())
コード例 #28
0
 def  test_tenant_schema_creation_in_specified_db(self):
     """
     When saving a tenant using a db, its schema should be created in 
     that db
     """
     db = random.choice(get_all_dbs())
     tenant = Tenant(domain_url='something1.test.com', 
                                 schema_name='test1')
     tenant.save(
         verbosity=BaseTestCase.get_verbosity(),
         using=db)
     for d in get_all_dbs():
         if d == db:
             self.assertTrue(schema_exists(
                                     tenant.schema_name,
                                     db=d))
         else:
             self.assertFalse(schema_exists(
                                     tenant.schema_name,
                                     db=d))
コード例 #29
0
    def setUp(self):
        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain,
                                    schema_name='public')
        self.public_tenant.save()

        connection.set_schema_to_public()
コード例 #30
0
    def test_tenant_apps_and_shared_apps_can_have_the_same_apps(self):
        """
        Tests that both SHARED_APPS and TENANT_APPS can have apps in common.
        In this case they should get synced to both tenant and public schemas.
        """
        settings.SHARED_APPS = ('tenant_schemas',  # 2 tables
                                'django.contrib.auth',  # 6 tables
                                'django.contrib.contenttypes',  # 1 table
                                'django.contrib.sessions', )  # 1 table
        settings.TENANT_APPS = ('django.contrib.sessions', )  # 1 table
        settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
        self.sync_shared()
        tenant = Tenant(domain_url='arbitrary.test.com', schema_name='test')
        tenant.save()

        shared_tables = self.get_tables_list_in_schema(get_public_schema_name())
        tenant_tables = self.get_tables_list_in_schema(tenant.schema_name)
        self.assertEqual(2+6+1+1+self.MIGRATION_TABLE_SIZE, len(shared_tables))
        self.assertIn('django_session', shared_tables)
        self.assertEqual(1+self.MIGRATION_TABLE_SIZE, len(tenant_tables))
        self.assertIn('django_session', tenant_tables)
コード例 #31
0
    def test_switching_search_path(self):
        dummies_tenant1_count, dummies_tenant2_count = 0, 0

        tenant1 = Tenant(domain_url='test.com', schema_name='tenant1')
        tenant1.save()

        tenant2 = Tenant(domain_url='example.com', schema_name='tenant2')
        tenant2.save()

        # go to tenant1's path
        connection.set_tenant(tenant1)

        # add some data
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()
        dummies_tenant1_count = DummyModel.objects.count()

        # switch temporarily to tenant2's path
        with tenant_context(tenant2):
            # add some data
            DummyModel(name="Man,").save()
            DummyModel(name="testing").save()
            DummyModel(name="is great!").save()
            dummies_tenant2_count = DummyModel.objects.count()

        # we should be back to tenant1's path, test what we have
        self.assertEqual(DummyModel.objects.count(), dummies_tenant1_count)

        # switch back to tenant2's path
        with tenant_context(tenant2):
            self.assertEqual(DummyModel.objects.count(), dummies_tenant2_count)
コード例 #32
0
    def test_switching_search_path(self):
        tenant1 = Tenant(domain_url='something.test.com',
                         schema_name='tenant1')
        tenant1.save()

        connection.set_schema_to_public()
        tenant2 = Tenant(domain_url='example.com', schema_name='tenant2')
        tenant2.save()

        # go to tenant1's path
        connection.set_tenant(tenant1)

        # add some data, 2 DummyModels for tenant1
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()

        # switch temporarily to tenant2's path
        with tenant_context(tenant2):
            # add some data, 3 DummyModels for tenant2
            DummyModel(name="Man,").save()
            DummyModel(name="testing").save()
            DummyModel(name="is great!").save()

        # we should be back to tenant1's path, test what we have
        self.assertEqual(2, DummyModel.objects.count())

        # switch back to tenant2's path
        with tenant_context(tenant2):
            self.assertEqual(3, DummyModel.objects.count())
コード例 #33
0
 def setUpClass(cls):        
     settings.SHARED_APPS = ('tenant_schemas', )
     settings.TENANT_APPS = ('dts_test_app',
                             'django.contrib.contenttypes',
                             'django.contrib.auth', )
     settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
     super(MultiDBTenantDataAndSettingsTest, cls).setUpClass()        
     for db in get_all_dbs():
         cls.sync_shared(db=db)
         Tenant(domain_url='test.com', schema_name=get_public_schema_name()).save(
                                                     verbosity=cls.get_verbosity(), 
                                                     using=db
                                                     )
コード例 #34
0
 def setUpClass(cls):
     super(TenantDataAndSettingsTest, cls).setUpClass()
     settings.SHARED_APPS = ("tenant_schemas", )
     settings.TENANT_APPS = (
         "dts_test_app",
         "django.contrib.contenttypes",
         "django.contrib.auth",
     )
     settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
     cls.sync_shared()
     Tenant(domain_url="test.com",
            schema_name=get_public_schema_name()).save(
                verbosity=cls.get_verbosity())
コード例 #35
0
class RoutesTestCase(BaseTestCase):
    def setUp(self):
        super(RoutesTestCase, self).setUp()
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save()

    def test_tenant_routing(self):
        """
        request path should not be altered
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.tenant)

    def test_public_schema_routing(self):
        """
        request path should not be altered
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.public_tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.public_tenant)
コード例 #36
0
    def test_edit_tenant(self):
        """
        when editing an existing tenant, all data should be kept
        """
        tenant = Tenant(domain_url='test.com', schema_name='test')
        tenant.save()

        # go to tenant's path
        connection.set_tenant(tenant)

        # add some data
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()

        # edit tenant
        tenant.domain_url = 'example.com'
        tenant.save()

        # test if data is still there
        self.assertEquals(DummyModel.objects.count(), 2)
コード例 #37
0
    def test_auto_drop_schema(self):
        """
        When deleting a tenant with auto_drop_schema=True, it should delete
        the schema associated with the tenant.
        """
        self.assertFalse(schema_exists('auto_drop_tenant'))
        Tenant.auto_drop_schema = True
        tenant = Tenant(domain_url='something.test.com',
                        schema_name='auto_drop_tenant')
        tenant.save(verbosity=BaseTestCase.get_verbosity())
        self.assertTrue(schema_exists(tenant.schema_name))
        cursor = connection.cursor()

        # Force pending trigger events to be executed
        cursor.execute('SET CONSTRAINTS ALL IMMEDIATE')

        tenant.delete()
        self.assertFalse(schema_exists(tenant.schema_name))
        Tenant.auto_drop_schema = False
コード例 #38
0
    def test_sync_tenant(self):
        """
        When editing an existing tenant, all data should be kept.
        """
        tenant = Tenant(domain_url='something.test.com', schema_name='test')
        tenant.save(verbosity=BaseTestCase.get_verbosity())

        # go to tenant's path
        connection.set_tenant(tenant)

        # add some data
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()

        # edit tenant
        connection.set_schema_to_public()
        tenant.domain_url = 'example.com'
        tenant.save(verbosity=BaseTestCase.get_verbosity())

        connection.set_tenant(tenant)

        # test if data is still there
        self.assertEqual(DummyModel.objects.count(), 2)
コード例 #39
0
    def test_edit_tenant(self):
        """
        when editing an existing tenant, all data should be kept
        """
        tenant = Tenant(domain_url='test.com', schema_name='test')
        tenant.save()

        # go to tenant's path
        connection.set_tenant(tenant)

        # add some data
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()

        # edit tenant
        tenant.domain_url = 'example.com'
        tenant.save()

        # test if data is still there
        self.assertEquals(DummyModel.objects.count(), 2)
コード例 #40
0
    def test_sync_tenant(self):
        """
        When editing an existing tenant, all data should be kept.
        """
        tenant = Tenant(domain_url='something.test.com', schema_name='test')
        tenant.save(verbosity=BaseTestCase.get_verbosity())

        # go to tenant's path
        connection.set_tenant(tenant)

        # add some data
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()

        # edit tenant
        connection.set_schema_to_public()
        tenant.domain_url = 'example.com'
        tenant.save(verbosity=BaseTestCase.get_verbosity())

        connection.set_tenant(tenant)

        # test if data is still there
        self.assertEquals(DummyModel.objects.count(), 2)
コード例 #41
0
class TenantTestCase(TransactionTestCase):
    @classmethod
    def setUpClass(cls):
        settings.TENANT_APPS = (
            'tenant_schemas',
            'django.contrib.contenttypes',
            'django.contrib.auth',
        )

    def setUp(self):
        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain,
                                    schema_name='public')
        self.public_tenant.save()

        connection.set_schema_to_public()

    def tearDown(self):
        """
        Delete all tenant schemas. Tenant schema are not deleted
        automatically by django.
        """
        connection.set_schema_to_public()
        do_not_delete = [get_public_schema_name(), 'information_schema']
        cursor = connection.cursor()

        # Use information_schema.schemata instead of pg_catalog.pg_namespace in
        # utils.schema_exists, so that we only "see" schemas that we own
        cursor.execute('SELECT schema_name FROM information_schema.schemata')

        for row in cursor.fetchall():
            if not row[0].startswith('pg_') and row[0] not in do_not_delete:
                print("Deleting schema %s" % row[0])
                cursor.execute('DROP SCHEMA %s CASCADE' % row[0])

        Tenant.objects.all().delete()
        NonAutoSyncTenant.objects.all().delete()

    def test_tenant_schema_is_created(self):
        """
        when saving a tenant, it's schema should be created
        """
        tenant = Tenant(domain_url='something.test.com', schema_name='test')
        tenant.save()

        self.assertTrue(schema_exists(tenant.schema_name))

    def test_non_auto_sync_tenant(self):
        """
        when saving a tenant that has the flag auto_create_schema as
        False, the schema should not be created when saving the tenant
        """
        self.assertFalse(schema_exists('non_auto_sync_tenant'))

        tenant = NonAutoSyncTenant(domain_url='something.test.com',
                                   schema_name='test')
        tenant.save()

        self.assertFalse(schema_exists(tenant.schema_name))

    def test_sync_tenant(self):
        """
        when editing an existing tenant, all data should be kept
        """
        tenant = Tenant(domain_url='something.test.com', schema_name='test')
        tenant.save()

        # go to tenant's path
        connection.set_tenant(tenant)

        # add some data
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()

        # edit tenant
        connection.set_schema_to_public()
        tenant.domain_url = 'example.com'
        tenant.save()

        connection.set_tenant(tenant)

        # test if data is still there
        self.assertEquals(DummyModel.objects.count(), 2)

    def test_switching_search_path(self):
        dummies_tenant1_count, dummies_tenant2_count = 0, 0

        tenant1 = Tenant(domain_url='something.test.com',
                         schema_name='tenant1')
        tenant1.save()

        connection.set_schema_to_public()
        tenant2 = Tenant(domain_url='example.com', schema_name='tenant2')
        tenant2.save()

        # go to tenant1's path
        connection.set_tenant(tenant1)

        # add some data
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()
        dummies_tenant1_count = DummyModel.objects.count()

        # switch temporarily to tenant2's path
        with tenant_context(tenant2):
            # add some data
            DummyModel(name="Man,").save()
            DummyModel(name="testing").save()
            DummyModel(name="is great!").save()
            dummies_tenant2_count = DummyModel.objects.count()

        # we should be back to tenant1's path, test what we have
        self.assertEqual(DummyModel.objects.count(), dummies_tenant1_count)

        # switch back to tenant2's path
        with tenant_context(tenant2):
            self.assertEqual(DummyModel.objects.count(), dummies_tenant2_count)

    def test_switching_tenant_without_previous_tenant(self):
        tenant = Tenant(domain_url='something.test.com', schema_name='test')
        tenant.save()

        connection.tenant = None
        with tenant_context(tenant):
            DummyModel(name="No exception please").save()

        connection.tenant = None
        with schema_context(tenant.schema_name):
            DummyModel(name="Survived it!").save()
コード例 #42
0
class CeleryTasksTests(BaseTestCase):
    def setUp(self):
        super(CeleryTasksTests, self).setUp()
        self.tenant1 = Tenant(domain_url='test1', schema_name='test1')
        self.tenant1.save()

        self.tenant2 = Tenant(domain_url='test2', schema_name='test2')
        self.tenant2.save()

        connection.set_tenant(self.tenant1)
        self.dummy1 = DummyModel.objects.create(name='test1')

        connection.set_tenant(self.tenant2)
        self.dummy2 = DummyModel.objects.create(name='test2')

        connection.set_schema_to_public()

    def test_basic_model_update(self):
        # We should be in public schema where dummies don't exist.
        for dummy in self.dummy1, self.dummy2:
            # Test both async and local versions.
            with self.assertRaises(DummyModel.DoesNotExist):
                update_task.apply_async(args=(dummy.pk, 'updated-name'))

            with self.assertRaises(DummyModel.DoesNotExist):
                update_task.apply(args=(dummy.pk, 'updated-name'))

        connection.set_tenant(self.tenant1)
        update_task.apply_async(args=(self.dummy1.pk, 'updated-name'))
        self.assertEqual(connection.schema_name, self.tenant1.schema_name)

        # The task restores the schema from before running the task, so we are
        # using the `tenant1` tenant now.
        model_count = DummyModel.objects.filter(name='updated-name').count()
        self.assertEqual(model_count, 1)

        connection.set_tenant(self.tenant2)
        model_count = DummyModel.objects.filter(name='updated-name').count()
        self.assertEqual(model_count, 0)

    def test_task_retry(self):
        # Schema name should persist through retry attempts.
        connection.set_tenant(self.tenant1)
        update_retry_task.apply_async(args=(self.dummy1.pk, 'updated-name'))

        model_count = DummyModel.objects.filter(name='updated-name').count()
        self.assertEqual(model_count, 1)

    def test_restoring_schema_name(self):
        update_task.apply_async(
            args=(self.dummy1.pk, 'updated-name'),
            kwargs={'_schema_name': self.tenant1.schema_name})
        self.assertEqual(connection.schema_name, get_public_schema_name())

        connection.set_tenant(self.tenant1)
        update_task.apply_async(
            args=(self.dummy2.pk, 'updated-name'),
            kwargs={'_schema_name': self.tenant2.schema_name})
        self.assertEqual(connection.schema_name, self.tenant1.schema_name)

        connection.set_tenant(self.tenant2)
        # The model does not exist in the public schema.
        with self.assertRaises(DummyModel.DoesNotExist):
            update_task.apply_async(
                args=(self.dummy2.pk, 'updated-name'),
                kwargs={'_schema_name': get_public_schema_name()})

        self.assertEqual(connection.schema_name, self.tenant2.schema_name)
コード例 #43
0
class RoutesTestCase(TransactionTestCase):
    @classmethod
    def setUpClass(cls):
        settings.TENANT_APPS = ('tenant_schemas',
                                'django.contrib.contenttypes',
                                'django.contrib.auth', )

    def setUp(self):
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain,
                                    schema_name='public')
        self.public_tenant.save()

        # add a test tenant
        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save()

    def tearDown(self):
        """
        Delete all tenant schemas. Tenant schema are not deleted
        automatically by django.
        """
        connection.set_schema_to_public()
        do_not_delete = [get_public_schema_name(), 'information_schema']
        cursor = connection.cursor()

        # Use information_schema.schemata instead of pg_catalog.pg_namespace in
        # utils.schema_exists, so that we only "see" schemas that we own
        cursor.execute('SELECT schema_name FROM information_schema.schemata')

        for row in cursor.fetchall():
            if not row[0].startswith('pg_') and row[0] not in do_not_delete:
                print("Deleting schema %s" % row[0])
                cursor.execute('DROP SCHEMA %s CASCADE' % row[0])

        Tenant.objects.all().delete()

    def test_tenant_routing(self):
        """
        request path should not be altered
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.tenant)

    def test_public_schema_routing(self):
        """
        request path should not be altered
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.public_tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.public_tenant)
コード例 #44
0
class RoutesTestCase(BaseTestCase):
    @classmethod
    def setUpClass(cls):
        super(RoutesTestCase, cls).setUpClass()
        settings.SHARED_APPS = ('tenant_schemas', )
        settings.TENANT_APPS = ('dts_test_app',
                                'django.contrib.contenttypes',
                                'django.contrib.auth', )
        settings.INSTALLED_APPS = settings.SHARED_APPS + settings.TENANT_APPS
        cls.sync_shared()
        cls.public_tenant = Tenant(domain_url='test.com', schema_name=get_public_schema_name())
        cls.public_tenant.save(verbosity=BaseTestCase.get_verbosity())

    def setUp(self):
        super(RoutesTestCase, self).setUp()
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()
        self.dtm = DefaultTenantMiddleware()

        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save(verbosity=BaseTestCase.get_verbosity())

        self.non_existent_domain = 'no-tenant.test.com'
        self.non_existent_tenant = Tenant(domain_url=self.non_existent_domain, schema_name='no-tenant')

        self.url = '/any/path/'

    def test_tenant_routing(self):
        request = self.factory.get(
            self.url, HTTP_HOST=self.tenant_domain)
        self.tm.process_request(request)
        self.assertEquals(request.path_info, self.url)
        self.assertEquals(request.tenant, self.tenant)

    def test_public_schema_routing(self):
        request = self.factory.get(
            self.url, HTTP_HOST=self.public_tenant.domain_url)
        self.tm.process_request(request)
        self.assertEquals(request.path_info, self.url)
        self.assertEquals(request.tenant, self.public_tenant)

    def test_non_existent_tenant_routing(self):
        """Raise 404 for unrecognised hostnames."""
        request = self.factory.get(
            self.url, HTTP_HOST=self.non_existent_tenant.domain_url)
        self.assertRaises(Http404, self.tm.process_request, request)

    def test_non_existent_tenant_to_default_schema_routing(self):
        """Route unrecognised hostnames to the 'public' tenant."""
        request = self.factory.get(
            self.url, HTTP_HOST=self.non_existent_tenant.domain_url)
        self.dtm.process_request(request)
        self.assertEquals(request.path_info, self.url)
        self.assertEquals(request.tenant, self.public_tenant)

    def test_non_existent_tenant_custom_middleware(self):
        """Route unrecognised hostnames to the 'test' tenant."""
        dtm = TestDefaultTenantMiddleware()
        request = self.factory.get(
            self.url, HTTP_HOST=self.non_existent_tenant.domain_url)
        dtm.process_request(request)
        self.assertEquals(request.path_info, self.url)
        self.assertEquals(request.tenant, self.tenant)

    def test_non_existent_tenant_and_default_custom_middleware(self):
        """Route unrecognised hostnames to the 'missing' tenant."""
        dtm = MissingDefaultTenantMiddleware()
        request = self.factory.get(
            self.url, HTTP_HOST=self.non_existent_tenant.domain_url)
        self.assertRaises(DisallowedHost, dtm.process_request, request)
コード例 #45
0
ファイル: tests.py プロジェクト: bufke/tenant-schemas-celery
class CeleryTasksTests(BaseTestCase):
    def setUp(self):
        super(CeleryTasksTests, self).setUp()
        self.tenant1 = Tenant(domain_url='test1', schema_name='test1')
        self.tenant1.save()

        self.tenant2 = Tenant(domain_url='test2', schema_name='test2')
        self.tenant2.save()

        connection.set_tenant(self.tenant1)
        self.dummy1 = DummyModel.objects.create(name='test1')

        connection.set_tenant(self.tenant2)
        self.dummy2 = DummyModel.objects.create(name='test2')

        connection.set_schema_to_public()

    def test_basic_model_update(self):
        # We should be in public schema where dummies don't exist.
        for dummy in self.dummy1, self.dummy2:
            # Test both async and local versions.
            with self.assertRaises(DummyModel.DoesNotExist):
                update_task.apply_async(args=(dummy.pk, 'updated-name'))

            with self.assertRaises(DummyModel.DoesNotExist):
                update_task.apply(args=(dummy.pk, 'updated-name'))

        connection.set_tenant(self.tenant1)
        update_task.apply_async(args=(self.dummy1.pk, 'updated-name'))
        self.assertEqual(connection.schema_name, self.tenant1.schema_name)

        # The task restores the schema from before running the task, so we are
        # using the `tenant1` tenant now.
        model_count = DummyModel.objects.filter(name='updated-name').count()
        self.assertEqual(model_count, 1)

        connection.set_tenant(self.tenant2)
        model_count = DummyModel.objects.filter(name='updated-name').count()
        self.assertEqual(model_count, 0)

    def test_task_retry(self):
        # Schema name should persist through retry attempts.
        connection.set_tenant(self.tenant1)
        update_retry_task.apply_async(args=(self.dummy1.pk, 'updated-name'))

        model_count = DummyModel.objects.filter(name='updated-name').count()
        self.assertEqual(model_count, 1)

    def test_restoring_schema_name(self):
        update_task.apply_async(
            args=(self.dummy1.pk, 'updated-name'),
            kwargs={'_schema_name': self.tenant1.schema_name}
        )
        self.assertEqual(connection.schema_name, get_public_schema_name())

        connection.set_tenant(self.tenant1)
        update_task.apply_async(
            args=(self.dummy2.pk, 'updated-name'),
            kwargs={'_schema_name': self.tenant2.schema_name}
        )
        self.assertEqual(connection.schema_name, self.tenant1.schema_name)

        connection.set_tenant(self.tenant2)
        # The model does not exist in the public schema.
        with self.assertRaises(DummyModel.DoesNotExist):
            update_task.apply_async(
                args=(self.dummy2.pk, 'updated-name'),
                kwargs={'_schema_name': get_public_schema_name()}
            )

        self.assertEqual(connection.schema_name, self.tenant2.schema_name)
コード例 #46
0
class TenantTestCase(TransactionTestCase):
    @classmethod
    def setUpClass(cls):
        settings.TENANT_APPS = ('tenant_schemas',
                                'django.contrib.contenttypes',
                                'django.contrib.auth', )

    def setUp(self):
        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain,
                                    schema_name='public')
        self.public_tenant.save()

        connection.set_schema_to_public()

    def tearDown(self):
        """
        Delete all tenant schemas. Tenant schema are not deleted
        automatically by django.
        """
        connection.set_schema_to_public()
        do_not_delete = [get_public_schema_name(), 'information_schema']
        cursor = connection.cursor()

        # Use information_schema.schemata instead of pg_catalog.pg_namespace in
        # utils.schema_exists, so that we only "see" schemas that we own
        cursor.execute('SELECT schema_name FROM information_schema.schemata')

        for row in cursor.fetchall():
            if not row[0].startswith('pg_') and row[0] not in do_not_delete:
                print("Deleting schema %s" % row[0])
                cursor.execute('DROP SCHEMA %s CASCADE' % row[0])

        Tenant.objects.all().delete()
        NonAutoSyncTenant.objects.all().delete()

    def test_tenant_schema_is_created(self):
        """
        when saving a tenant, it's schema should be created
        """
        tenant = Tenant(domain_url='something.test.com', schema_name='test')
        tenant.save()

        self.assertTrue(schema_exists(tenant.schema_name))

    def test_non_auto_sync_tenant(self):
        """
        when saving a tenant that has the flag auto_create_schema as
        False, the schema should not be created when saving the tenant
        """
        self.assertFalse(schema_exists('non_auto_sync_tenant'))

        tenant = NonAutoSyncTenant(domain_url='something.test.com',
                                   schema_name='test')
        tenant.save()

        self.assertFalse(schema_exists(tenant.schema_name))

    def test_sync_tenant(self):
        """
        when editing an existing tenant, all data should be kept
        """
        tenant = Tenant(domain_url='something.test.com', schema_name='test')
        tenant.save()

        # go to tenant's path
        connection.set_tenant(tenant)

        # add some data
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()

        # edit tenant
        connection.set_schema_to_public()
        tenant.domain_url = 'example.com'
        tenant.save()

        connection.set_tenant(tenant)

        # test if data is still there
        self.assertEquals(DummyModel.objects.count(), 2)

    def test_switching_search_path(self):
        dummies_tenant1_count, dummies_tenant2_count = 0, 0

        tenant1 = Tenant(domain_url='something.test.com',
                         schema_name='tenant1')
        tenant1.save()

        connection.set_schema_to_public()
        tenant2 = Tenant(domain_url='example.com', schema_name='tenant2')
        tenant2.save()

        # go to tenant1's path
        connection.set_tenant(tenant1)

        # add some data
        DummyModel(name="Schemas are").save()
        DummyModel(name="awesome!").save()
        dummies_tenant1_count = DummyModel.objects.count()

        # switch temporarily to tenant2's path
        with tenant_context(tenant2):
            # add some data
            DummyModel(name="Man,").save()
            DummyModel(name="testing").save()
            DummyModel(name="is great!").save()
            dummies_tenant2_count = DummyModel.objects.count()

        # we should be back to tenant1's path, test what we have
        self.assertEqual(DummyModel.objects.count(), dummies_tenant1_count)

        # switch back to tenant2's path
        with tenant_context(tenant2):
            self.assertEqual(DummyModel.objects.count(), dummies_tenant2_count)
コード例 #47
0
class RoutesTestCase(TransactionTestCase):
    @classmethod
    def setUpClass(cls):
        settings.TENANT_APPS = (
            'tenant_schemas',
            'django.contrib.contenttypes',
            'django.contrib.auth',
        )

    def setUp(self):
        self.factory = RequestFactory()
        self.tm = TenantMiddleware()

        # settings needs some patching
        settings.TENANT_MODEL = 'tenant_schemas.Tenant'

        # add the public tenant
        self.public_tenant_domain = 'test.com'
        self.public_tenant = Tenant(domain_url=self.public_tenant_domain,
                                    schema_name='public')
        self.public_tenant.save()

        # add a test tenant
        self.tenant_domain = 'tenant.test.com'
        self.tenant = Tenant(domain_url=self.tenant_domain, schema_name='test')
        self.tenant.save()

    def tearDown(self):
        """
        Delete all tenant schemas. Tenant schema are not deleted
        automatically by django.
        """
        connection.set_schema_to_public()
        do_not_delete = [get_public_schema_name(), 'information_schema']
        cursor = connection.cursor()

        # Use information_schema.schemata instead of pg_catalog.pg_namespace in
        # utils.schema_exists, so that we only "see" schemas that we own
        cursor.execute('SELECT schema_name FROM information_schema.schemata')

        for row in cursor.fetchall():
            if not row[0].startswith('pg_') and row[0] not in do_not_delete:
                print("Deleting schema %s" % row[0])
                cursor.execute('DROP SCHEMA %s CASCADE' % row[0])

        Tenant.objects.all().delete()

    def test_tenant_routing(self):
        """
        request path should not be altered
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.tenant)

    def test_public_schema_routing(self):
        """
        request path should not be altered
        """
        request_url = '/any/request/'
        request = self.factory.get('/any/request/',
                                   HTTP_HOST=self.public_tenant_domain)
        self.tm.process_request(request)

        self.assertEquals(request.path_info, request_url)

        # request.tenant should also have been set
        self.assertEquals(request.tenant, self.public_tenant)