# Path: boardinghouse/schema.py
# def get_active_schema():
#     """
#     Get the (internal) name of the currently active schema.
#     """
#     return _get_schema(get_active_schema_name())
# 
# def get_schema_model():
#     """
#     Return the class that is currently set as the schema model.
#     """
#     try:
#         return apps.get_model(settings.BOARDINGHOUSE_SCHEMA_MODEL)
#     except AttributeError:
#         raise ImproperlyConfigured("BOARDINGHOUSE_SCHEMA_MODEL is not set: is 'boardinghouse' in your INSTALLED_APPS?")
#     except ValueError:
#         raise ImproperlyConfigured("BOARDINGHOUSE_SCHEMA_MODEL must be of the form 'app_label.model_name'")
#     except LookupError:
#         raise ImproperlyConfigured(
#             "BOARDINGHOUSE_SCHEMA_MODEL refers to model '{0!s}' that has not been installed".format(
#                 settings.BOARDINGHOUSE_SCHEMA_MODEL))
# 
# Path: boardinghouse/exceptions.py
# class TemplateSchemaActivation(Forbidden):
#     """
#     An exception that will be raised when a user attempts to activate
#     the settings.TEMPLATE_SCHEMA schema.
#     """
#     def __init__(self, *args, **kwargs):
#         super(TemplateSchemaActivation, self).__init__(
#             'Activating template schema forbidden.', *args, **kwargs
#         )
# 
# class SchemaNotFound(Exception):
#     """
#     An exception that is raised when an attempt to activate a schema that
#     is not in the database is made.
#     """
# 
# class SchemaRequiredException(Exception):
#     """
#     An exception raised when an operation requires a schema to be active
#     or supplied, but none was provided.
#     """
# 
# Path: tests/models.py
# class AwareModel(models.Model):
#     name = models.CharField(max_length=10, unique=True)
#     status = models.BooleanField(default=False)
#     factor = models.PositiveSmallIntegerField(default=7)
# 
#     objects = MultiSchemaManager()
# 
# class NaiveModel(SharedSchemaModel):
#     name = models.CharField(max_length=10, unique=True)
#     status = models.BooleanField(default=False)


import json
import sys
import unittest
from contextlib import contextmanager
from django.core.management import call_command
from django.db import connection, DatabaseError
from django.test import TestCase
from django.utils import six
from boardinghouse.schema import get_active_schema, get_schema_model
from boardinghouse.exceptions import TemplateSchemaActivation, SchemaNotFound, SchemaRequiredException
from ..models import AwareModel, NaiveModel

class TestLoadData(TestCase):
    def test_invalid_schema_causes_error(self):
        with self.assertRaises(SchemaNotFound):
            call_command('loaddata', 'foo', schema='foo')

    def test_loading_schemata_creates_pg_schemata(self):
        self.assertEqual(0, Schema.objects.count())
        # Need to use commit=False, else the data will be in a different transaction.
        with capture(call_command, 'loaddata', 'tests/fixtures/schemata.json', commit=False) as output:
            self.assertEqual('Installed 2 object(s) from 1 fixture(s)\n', output)
        self.assertEqual(2, Schema.objects.count())
        Schema.objects.all()[0].activate()
        self.assertTrue(get_active_schema())
        cursor = connection.cursor()
        for schema in Schema.objects.all():
            cursor.execute(SCHEMA_QUERY, [schema.schema])
            data = cursor.fetchone()
            self.assertEqual((schema.schema,), data)
        cursor.close()

    def test_loading_naive_data_does_not_require_schema_arg(self):
        with capture(call_command, 'loaddata', 'tests/fixtures/naive.json', commit=False) as output:
            self.assertEqual('Installed 2 object(s) from 1 fixture(s)\n', output)
        NaiveModel.objects.get(name="naive1")

    def test_loading_naive_data_works_with_schema_passed_in(self):
        Schema.objects.create(name='a', schema='a')
        with capture(call_command, 'loaddata', 'tests/fixtures/naive.json', schema='a', commit=False) as output:
            self.assertEqual('Installed 2 object(s) from 1 fixture(s)\n', output)

# Path: boardinghouse/schema.py
# def get_active_schema():
#     """
#     Get the (internal) name of the currently active schema.
#     """
#     return _get_schema(get_active_schema_name())
# 
# def get_schema_model():
#     """
#     Return the class that is currently set as the schema model.
#     """
#     try:
#         return apps.get_model(settings.BOARDINGHOUSE_SCHEMA_MODEL)
#     except AttributeError:
#         raise ImproperlyConfigured("BOARDINGHOUSE_SCHEMA_MODEL is not set: is 'boardinghouse' in your INSTALLED_APPS?")
#     except ValueError:
#         raise ImproperlyConfigured("BOARDINGHOUSE_SCHEMA_MODEL must be of the form 'app_label.model_name'")
#     except LookupError:
#         raise ImproperlyConfigured(
#             "BOARDINGHOUSE_SCHEMA_MODEL refers to model '{0!s}' that has not been installed".format(
#                 settings.BOARDINGHOUSE_SCHEMA_MODEL))
# 
# Path: boardinghouse/exceptions.py
# class TemplateSchemaActivation(Forbidden):
#     """
#     An exception that will be raised when a user attempts to activate
#     the settings.TEMPLATE_SCHEMA schema.
#     """
#     def __init__(self, *args, **kwargs):
#         super(TemplateSchemaActivation, self).__init__(
#             'Activating template schema forbidden.', *args, **kwargs
#         )
# 
# class SchemaNotFound(Exception):
#     """
#     An exception that is raised when an attempt to activate a schema that
#     is not in the database is made.
#     """
# 
# class SchemaRequiredException(Exception):
#     """
#     An exception raised when an operation requires a schema to be active
#     or supplied, but none was provided.
#     """
# 
# Path: tests/models.py
# class AwareModel(models.Model):
#     name = models.CharField(max_length=10, unique=True)
#     status = models.BooleanField(default=False)
#     factor = models.PositiveSmallIntegerField(default=7)
# 
#     objects = MultiSchemaManager()
# 
# class NaiveModel(SharedSchemaModel):
#     name = models.CharField(max_length=10, unique=True)
#     status = models.BooleanField(default=False)


# Path: tests/tests/test_management_commands.py
import json
import sys
import unittest
from contextlib import contextmanager
from django.core.management import call_command
from django.db import connection, DatabaseError
from django.test import TestCase
from django.utils import six
from boardinghouse.schema import get_active_schema, get_schema_model
from boardinghouse.exceptions import TemplateSchemaActivation, SchemaNotFound, SchemaRequiredException
from ..models import AwareModel, NaiveModel


class TestLoadData(TestCase):
    def test_invalid_schema_causes_error(self):
        with self.assertRaises(SchemaNotFound):
            call_command('loaddata', 'foo', schema='foo')

    def test_loading_schemata_creates_pg_schemata(self):
        self.assertEqual(0, Schema.objects.count())
        # Need to use commit=False, else the data will be in a different transaction.
        with capture(call_command, 'loaddata', 'tests/fixtures/schemata.json', commit=False) as output:
            self.assertEqual('Installed 2 object(s) from 1 fixture(s)\n', output)
        self.assertEqual(2, Schema.objects.count())
        Schema.objects.all()[0].activate()
        self.assertTrue(get_active_schema())
        cursor = connection.cursor()
        for schema in Schema.objects.all():
            cursor.execute(SCHEMA_QUERY, [schema.schema])
            data = cursor.fetchone()
            self.assertEqual((schema.schema,), data)
        cursor.close()

    def test_loading_naive_data_does_not_require_schema_arg(self):
        with capture(call_command, 'loaddata', 'tests/fixtures/naive.json', commit=False) as output:
            self.assertEqual('Installed 2 object(s) from 1 fixture(s)\n', output)
        NaiveModel.objects.get(name="naive1")

    def test_loading_naive_data_works_with_schema_passed_in(self):
        Schema.objects.create(name='a', schema='a')
        with capture(call_command, 'loaddata', 'tests/fixtures/naive.json', schema='a', commit=False) as output:
            self.assertEqual('Installed 2 object(s) from 1 fixture(s)\n', output)

        NaiveModel.objects.get(name="naive1")