import sys
import environ
import os
import django
from django.apps import apps
from django.test import TestCase
from model_bakery import baker
sys.path.append(str(environ.Path(__file__) - 3))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
django.setup()

{% for model, options in model_dict.items() %}
class {{model.__name__}}Tests(TestCase):
    """ test CRUD operations on {{ model.__name__ }} """
    def setUp(self):
        self.model = apps.get_model('{{ model._meta.app_label }}', '{{ model._meta.model_name }}')
        self.to_bake = '{{model._meta.label}}'
        {% if options['update_field_list'] %}self.field_to_update = self.model.{{ options['update_field_list'][0].name }}{% else %}self.field_to_update = None{% endif %}
        {%- if options['fk_dependancies'] %}{%- for fk_field in options['fk_dependancies'] %}
        self.{{ fk_field.name }} = baker.make(apps.get_model('{{ model._meta.app_label }}', '{{ fk_field.related_model._meta.model_name }}'), _fill_optional=True){% endfor %}{%- endif %}

    def bake(self):
        """ add row """
        return baker.make(self.to_bake, {% if options['fk_dependancies'] %}{% for fk_field in options['fk_dependancies'] %}{{ fk_field.name }}=self.{{ fk_field.name }}, {% endfor %}{% endif %}{% if options['fill_optional'] %}_fill_optional={{ options['fill_optional'] }}{% endif %})

    def test_create(self):
        """ verify object can be created """
        before_count = self.model.objects.count()
        row = self.bake()
        after_count = self.model.objects.count()
        self.assertTrue(isinstance(row, self.model))
        self.assertGreater(after_count, before_count)

    def test_read(self):
        """ verify object can be read """
        row = self.bake()
        entry = self.model.objects.get(id=row.id)
        self.assertTrue(isinstance(entry, self.model))
        self.assertEqual(row.id, entry.id)

    {%- if self.field_to_update %}
    def test_update(self):
        """ verify object can be updated """
        row = self.bake()
        {% if self.field_to_update.get_internal_type() == 'ForeignKey' -%}
        updated_value = baker.make('{{ self.field_to_update.related_model._meta.app_label }}.{{ self.field_to_update.related_model._meta.model_name }}')
        {% elif self.field_to_update.get_internal_type() == 'CharField' -%}
        updated_value = baker.prepare(self.to_bake, _fill_optional=['{{ self.field_to_update.name }}']).{{ self.field_to_update.name }}
        {% elif self.field_to_update.get_internal_type() == 'TextField' -%}
        updated_value = baker.prepare(self.to_bake, _fill_optional=['{{ self.field_to_update.name }}']).{{ self.field_to_update.name }}
        {% endif -%}
        setattr(row, '{{ self.field_to_update.name }}', updated_value)
        row.save()
        self.assertEqual(getattr(row, self.field_to_update), updated){% endif %}

    def test_delete(self):
        """ verify object can be deleted """
        row = self.bake()
        before_count = self.model.objects.count()
        row_id = row.id
        row.delete()
        after_count = self.model.objects.count()
        with self.assertRaises(self.model.DoesNotExist):
            self.model.objects.get(id=row_id)
        self.assertLess(after_count, before_count)

{% endfor %}