From 2bbfe7dd1c7a229e0fb6b5ff9e3bcc377fff6da2 Mon Sep 17 00:00:00 2001
From: Matthew Dillon <matthewrdillon@gmail.com>
Date: Thu, 9 Jun 2016 12:21:37 -0700
Subject: [PATCH] misc: tests and data migration

---
 ccdb/misc/factories.py                    |  61 ++++++++++++
 ccdb/misc/migrations/0002_DATA_initial.py | 111 ++++++++++++++++++++++
 ccdb/misc/tests/__init__.py               |   0
 ccdb/misc/tests/test_models.py            |  62 ++++++++++++
 4 files changed, 234 insertions(+)
 create mode 100644 ccdb/misc/factories.py
 create mode 100644 ccdb/misc/migrations/0002_DATA_initial.py
 create mode 100644 ccdb/misc/tests/__init__.py
 create mode 100644 ccdb/misc/tests/test_models.py

diff --git a/ccdb/misc/factories.py b/ccdb/misc/factories.py
new file mode 100644
index 0000000..c0fc42b
--- /dev/null
+++ b/ccdb/misc/factories.py
@@ -0,0 +1,61 @@
+import factory
+
+from .models import MeasurementUnit, MeasurementType, Material, Color, Container
+
+
+class MeasurementUnitFactory(factory.DjangoModelFactory):
+    class Meta:
+        model = MeasurementUnit
+
+    name = factory.Sequence(lambda n: 'measurement_unit{}'.format(n))
+    code = factory.Sequence(lambda n: 'mu{}'.format(n))
+    unit_class = 'abc'
+    description = 'lorem ipsum'
+    sort_order = factory.Sequence(lambda n: n)
+
+
+class MeasurementTypeFactory(factory.DjangoModelFactory):
+    class Meta:
+        model = MeasurementType
+
+    name = factory.Sequence(lambda n: 'measurement_type{}'.format(n))
+    code = factory.Sequence(lambda n: 'mt{}'.format(n))
+    measurement_type_class = 'abc'
+    description = 'lorem ipsum'
+    default_measurement_unit = factory.SubFactory(MeasurementUnitFactory)
+    sort_order = factory.Sequence(lambda n: n)
+
+
+class MaterialFactory(factory.DjangoModelFactory):
+    class Meta:
+        model = Material
+
+    name = factory.Sequence(lambda n: 'material{}'.format(n))
+    code = factory.Sequence(lambda n: 'm{}'.format(n))
+    material_class = 'abc'
+    description = 'lorem ipsum'
+    sort_order = factory.Sequence(lambda n: n)
+
+
+class ColorFactory(factory.DjangoModelFactory):
+    class Meta:
+        model = Color
+
+    name = factory.Sequence(lambda n: 'color{}'.format(n))
+    code = factory.Sequence(lambda n: 'c{}'.format(n))
+    color_number = factory.Sequence(lambda n: float(n))
+    sort_order = factory.Sequence(lambda n: n)
+
+
+class ContainerFactory(factory.DjangoModelFactory):
+    class Meta:
+        model = Container
+
+    name = factory.Sequence(lambda n: 'container{}'.format(n))
+    code = factory.Sequence(lambda n: 'c{}'.format(n))
+    application = 'asdf'
+    color = factory.SubFactory(ColorFactory)
+    material = factory.SubFactory(MaterialFactory)
+    volume = factory.Sequence(lambda n: float(n))
+    measurement_unit = factory.SubFactory(MeasurementUnitFactory)
+    sort_order = factory.Sequence(lambda n: n)
diff --git a/ccdb/misc/migrations/0002_DATA_initial.py b/ccdb/misc/migrations/0002_DATA_initial.py
new file mode 100644
index 0000000..30d639c
--- /dev/null
+++ b/ccdb/misc/migrations/0002_DATA_initial.py
@@ -0,0 +1,111 @@
+from django.db import migrations
+from django.forms import modelform_factory
+
+from ccdb.utils.data import get_data_sources
+
+
+class Migration(migrations.Migration):
+    def migrate(apps, schema_editor):
+        sources = get_data_sources()
+        if not sources:
+            return
+
+        c = sources['db0']
+
+        MeasurementUnit = apps.get_model('misc', 'MeasurementUnit')
+        MeasurementType = apps.get_model('misc', 'MeasurementType')
+        Material = apps.get_model('misc', 'Material')
+        Color = apps.get_model('misc', 'Color')
+        Container = apps.get_model('misc', 'Container')
+
+        for model in [Container, MeasurementType, MeasurementUnit, Material, Color]:
+            model.objects.all().delete()
+
+        MUnitForm = modelform_factory(MeasurementUnit, fields=('name', 'code',
+                                                               'unit_class',
+                                                               'description',
+                                                               'sort_order'))
+        MTypeForm = modelform_factory(MeasurementType, fields=('name', 'code',
+                                                               'measurement_type_class',
+                                                               'description',
+                                                               'default_measurement_unit',
+                                                               'sort_order'))
+        MaterialForm = modelform_factory(Material, fields=('name', 'code',
+                                                           'material_class',
+                                                           'description',
+                                                           'sort_order'))
+        ColorForm = modelform_factory(Color, fields=('name', 'code',
+                                                     'color_number',
+                                                     'sort_order'))
+        ContainerForm = modelform_factory(Container, fields=('name', 'code',
+                                                             'application',
+                                                             'color', 'material',
+                                                             'volume',
+                                                             'measurement_unit',
+                                                             'sort_order'))
+
+        for r in c.execute('SELECT * FROM tbl_lu_measurement_units;'):
+            form = MUnitForm(dict(name=r[1], code=r[2],
+                                  unit_class=r[3], description=r[4],
+                                  sort_order=int(r[5]) if r[5] else None))
+            if form.is_valid():
+                MeasurementUnit.objects.create(id=r[0], **form.cleaned_data)
+            else:
+                print('measurement unit', r[0:], form.errors.as_data())
+
+        for r in c.execute('SELECT * FROM tbl_lu_measurement_types;'):
+            form = MTypeForm(dict(name=r[1], code=r[2],
+                                  measurement_type_class=r[3], description=r[4],
+                                  default_measurement_unit=r[5],
+                                  sort_order=int(r[6]) if r[6] else None))
+            if form.is_valid():
+                MeasurementType.objects.create(id=r[0], **form.cleaned_data)
+            else:
+                print('measurement type', r[0:], form.errors.as_data())
+
+        for r in c.execute('SELECT * FROM tbl_lu_materials;'):
+            form = MaterialForm(dict(name=r[1], code=r[2],
+                                     material_class=r[3], description=r[4],
+                                     sort_order=int(r[5]) if r[5] else None))
+            if form.is_valid():
+                Material.objects.create(id=r[0], **form.cleaned_data)
+            else:
+                print('material', r[0:], form.errors.as_data())
+
+        for r in c.execute('SELECT * FROM tbl_lu_colors;'):
+            form = ColorForm(dict(name=r[1], code=r[2],
+                                  color_number=float(r[3]) if r[3] else None,
+                                  sort_order=int(r[4]) if r[4] else None))
+            if form.is_valid():
+                Color.objects.create(id=r[0], **form.cleaned_data)
+            else:
+                print('color', r[0:], form.errors.as_data())
+
+        for r in c.execute('SELECT * FROM tbl_lu_containers;'):
+            form = ContainerForm(dict(name=r[1], code=r[2],
+                                      application=r[3], color=r[4], material=r[5],
+                                      volume=float(r[6]) if r[6] else None,
+                                      measurement_unit=r[7],
+                                      sort_order=int(r[8]) if r[8] else None))
+            if form.is_valid():
+                Container.objects.create(id=r[0], **form.cleaned_data)
+            else:
+                print('container', r[0:], form.errors.as_data())
+
+    def rollback(apps, schema_editor):
+        MeasurementUnit = apps.get_model('misc', 'MeasurementUnit')
+        MeasurementType = apps.get_model('misc', 'MeasurementType')
+        Material = apps.get_model('misc', 'Material')
+        Color = apps.get_model('misc', 'Color')
+        Container = apps.get_model('misc', 'Container')
+
+        for model in [Container, MeasurementType, MeasurementUnit, Material, Color]:
+            model.objects.all().delete()
+
+    dependencies = [
+        ('misc', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.RunPython(migrate, rollback),
+    ]
diff --git a/ccdb/misc/tests/__init__.py b/ccdb/misc/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/ccdb/misc/tests/test_models.py b/ccdb/misc/tests/test_models.py
new file mode 100644
index 0000000..354a3a6
--- /dev/null
+++ b/ccdb/misc/tests/test_models.py
@@ -0,0 +1,62 @@
+from django.test import TestCase
+from django.db import IntegrityError, transaction
+
+from ..models import MeasurementUnit, MeasurementType, Material, Color, Container
+from ..factories import MeasurementUnitFactory, MeasurementTypeFactory, \
+    MaterialFactory, ColorFactory, ContainerFactory
+
+
+class MeasurementUnitTestCase(TestCase):
+    def test_creation(self):
+        m = MeasurementUnitFactory()
+        self.assertTrue(isinstance(m, MeasurementUnit))
+        self.assertEqual(m.__str__(), m.code)
+
+    def test_uniqueness(self):
+        m1 = MeasurementUnitFactory()
+        with transaction.atomic(), self.assertRaises(IntegrityError):
+            MeasurementUnitFactory(name=m1.name, code=m1.code)
+        m3 = MeasurementUnitFactory()
+        self.assertTrue(isinstance(m3, MeasurementUnit))
+
+
+class MeasurementTypeTestCase(TestCase):
+    def test_creation(self):
+        m = MeasurementTypeFactory()
+        self.assertTrue(isinstance(m, MeasurementType))
+        self.assertEqual(m.__str__(), m.name)
+
+
+class MaterialTestCase(TestCase):
+    def test_creation(self):
+        m = MaterialFactory()
+        self.assertTrue(isinstance(m, Material))
+        self.assertEqual(m.__str__(), m.name)
+
+    def test_uniqueness(self):
+        m1 = MaterialFactory()
+        with transaction.atomic(), self.assertRaises(IntegrityError):
+            MaterialFactory(name=m1.name, code=m1.code)
+        m3 = MaterialFactory()
+        self.assertTrue(isinstance(m3, Material))
+
+
+class ColorTestCase(TestCase):
+    def test_creation(self):
+        c = ColorFactory()
+        self.assertTrue(isinstance(c, Color))
+        self.assertEqual(c.__str__(), c.name)
+
+    def test_uniqueness(self):
+        c1 = ColorFactory()
+        with transaction.atomic(), self.assertRaises(IntegrityError):
+            ColorFactory(name=c1.name, code=c1.code, color_number=c1.color_number)
+        c3 = ColorFactory()
+        self.assertTrue(isinstance(c3, Color))
+
+
+class ContainerTestCase(TestCase):
+    def test_creation(self):
+        c = ContainerFactory()
+        self.assertTrue(isinstance(c, Container))
+        self.assertEqual(c.__str__(), c.name)