diff --git a/ccdb/locations/factories.py b/ccdb/locations/factories.py new file mode 100644 index 0000000..82edd29 --- /dev/null +++ b/ccdb/locations/factories.py @@ -0,0 +1,63 @@ +from factory import DjangoModelFactory, Sequence, SubFactory +from factory.fuzzy import FuzzyText, FuzzyChoice, FuzzyInteger + +from .models import Region, Site, MunicipalLocation, StudyLocation, StorageLocation + + +class RegionFactory(DjangoModelFactory): + class Meta: + model = Region + + name = Sequence(lambda n: 'region{}'.format(n)) + code = Sequence(lambda n: 'r{}'.format(n)) + sort_order = Sequence(lambda n: n) + + +class SiteFactory(DjangoModelFactory): + class Meta: + model = Site + + region = SubFactory(RegionFactory) + name = Sequence(lambda n: 'site{}'.format(n)) + code = Sequence(lambda n: 's{}'.format(n)) + description = FuzzyText(length=100) + sort_order = Sequence(lambda n: n) + + +class MunicipalLocationFactory(DjangoModelFactory): + class Meta: + model = MunicipalLocation + + name = Sequence(lambda n: 'municipal_location{}'.format(n)) + code = Sequence(lambda n: 'ml{}'.format(n)) + municipal_location_type = FuzzyText(length=50) + description = FuzzyText(length=255) + sort_order = Sequence(lambda n: n) + + +class StudyLocationFactory(DjangoModelFactory): + class Meta: + model = StudyLocation + + site = SubFactory(SiteFactory) + name = Sequence(lambda n: 'study_location{}'.format(n)) + code = Sequence(lambda n: 'sl{}'.format(n)) + treatment_type = FuzzyText(length=100) + municipal_location = SubFactory(MunicipalLocationFactory) + collecting_location = FuzzyChoice([True, False]) + description = FuzzyText(length=255) + sort_order = Sequence(lambda n: n) + + +class StorageLocationFactory(DjangoModelFactory): + class Meta: + model = StorageLocation + + code = Sequence(lambda n: 'sl{}'.format(n)) + facility = FuzzyText(length=100) + building = FuzzyText(length=100) + room = FuzzyText(length=50) + freezer = FuzzyText(length=50) + temp_c = FuzzyInteger(-100, 100) + description = FuzzyText(length=255) + sort_order = Sequence(lambda n: n) diff --git a/ccdb/locations/migrations/0004_DATA_initial.py b/ccdb/locations/migrations/0004_DATA_initial.py new file mode 100644 index 0000000..f586a15 --- /dev/null +++ b/ccdb/locations/migrations/0004_DATA_initial.py @@ -0,0 +1,102 @@ +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'] + + Region = apps.get_model('locations', 'Region') + Site = apps.get_model('locations', 'Site') + MunicipalLocation = apps.get_model('locations', 'MunicipalLocation') + StudyLocation = apps.get_model('locations', 'StudyLocation') + StorageLocation = apps.get_model('locations', 'StorageLocation') + + for model in [StorageLocation, StudyLocation, MunicipalLocation, Site, Region]: + model.objects.all().delete() + + RegionForm = modelform_factory(Region, fields='__all__') + SiteForm = modelform_factory(Site, fields='__all__') + MunicipalLocationForm = modelform_factory(MunicipalLocation, fields='__all__') + StudyLocationForm = modelform_factory(StudyLocation, fields='__all__') + StorageLocationForm = modelform_factory(StorageLocation, fields='__all__') + + for r in c.execute('SELECT * FROM tbl_lu_regions;'): + form = RegionForm(dict(name=r[1], code=r[2], + sort_order=int(r[3]) if r[3] else None)) + if form.is_valid(): + Region.objects.create(id=r[0], **form.cleaned_data) + else: + print('region', r[0:], form.errors.as_data()) + + for r in c.execute('SELECT * FROM tbl_lu_sites;'): + form = SiteForm(dict(region=r[0], name=r[2], code=r[3], + description=r[4], + sort_order=int(r[5]) if r[5] else None)) + if form.is_valid(): + Site.objects.create(id=r[1], **form.cleaned_data) + else: + print('site', r[0:], form.errors.as_data()) + + for r in c.execute('SELECT * FROM tbl_lu_municipal_locations;'): + form = MunicipalLocationForm(dict(name=r[2], code=r[3], + municipal_location_type=r[4], + description=r[5], + sort_order=int(r[6]) if r[6] else None)) + if form.is_valid(): + MunicipalLocation.objects.create(id=r[1], **form.cleaned_data) + else: + print('municipal location', r[0:], form.errors.as_data()) + + for r in c.execute('SELECT * FROM tbl_lu_study_locations;'): + form = StudyLocationForm(dict(site=r[0], name=r[2], code=r[3], + study_location_type=r[4], + treatment_type=r[5], + municipal_location=r[6], + collection_location=r[7], + description=r[13], + sort_order=int(r[14]) if r[14] else None)) + if form.is_valid(): + StudyLocation.objects.create(id=r[1], **form.cleaned_data) + else: + print('study location', r[0:], form.errors.as_data()) + + for r in c.execute('SELECT * FROM tbl_lu_storage_locations;'): + bldg = ''.join(e[0].upper() for e in r[2].split()) + temp_c = r[5] if r[5] else '20' + freezer = r[4] if r[4] else 'No Freezer' + code = ' '.join([bldg, str(temp_c)+'C', str(freezer)]) + form = StorageLocationForm(dict(facility=r[1], building=r[2], room=r[3], + freezer=r[4], + temp_c=int(r[5]) if r[5] else None, + code=code, + description=r[6], + sort_order=int(r[7]) if r[7] else None)) + if form.is_valid(): + StorageLocation.objects.create(id=r[0], **form.cleaned_data) + else: + print('storage location', r[0:], form.errors.as_data()) + + def rollback(apps, schema_editor): + Region = apps.get_model('locations', 'Region') + Site = apps.get_model('locations', 'Site') + MunicipalLocation = apps.get_model('locations', 'MunicipalLocation') + StudyLocation = apps.get_model('locations', 'StudyLocation') + StorageLocation = apps.get_model('locations', 'StorageLocation') + + for model in [StorageLocation, StudyLocation, MunicipalLocation, Site, Region]: + model.objects.all().delete() + + dependencies = [ + ('locations', '0003_study_location_code_req'), + ] + + operations = [ + migrations.RunPython(migrate, rollback), + ] diff --git a/ccdb/locations/tests/__init__.py b/ccdb/locations/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ccdb/locations/tests/test_models.py b/ccdb/locations/tests/test_models.py new file mode 100644 index 0000000..4f114d3 --- /dev/null +++ b/ccdb/locations/tests/test_models.py @@ -0,0 +1,58 @@ +from django.test import TestCase +from django.db import IntegrityError, transaction + +from ..models import Region, Site, MunicipalLocation, StudyLocation, StorageLocation +from ..factories import RegionFactory, SiteFactory, MunicipalLocationFactory, \ + StudyLocationFactory, StorageLocationFactory + + +class RegionTestCase(TestCase): + def test_creation(self): + r = RegionFactory() + self.assertTrue(isinstance(r, Region)) + self.assertEqual(r.__str__(), r.name) + + def test_uniqueness(self): + r1 = RegionFactory() + with transaction.atomic(), self.assertRaises(IntegrityError): + RegionFactory(name=r1.name, code=r1.code) + r3 = RegionFactory() + self.assertTrue(isinstance(r3, Region)) + + +class SiteTestCase(TestCase): + def test_creation(self): + s = SiteFactory() + self.assertTrue(isinstance(s, Site)) + self.assertEqual(s.__str__(), s.name) + + +class MunicipalLocationTestCase(TestCase): + def test_creation(self): + m = MunicipalLocationFactory() + self.assertTrue(isinstance(m, MunicipalLocation)) + self.assertEqual(m.__str__(), m.name) + + +class StudyLocationTestCase(TestCase): + def test_creation(self): + s = StudyLocationFactory() + self.assertTrue(isinstance(s, StudyLocation)) + self.assertEqual(s.__str__(), s.code) + + def test_uniqueness(self): + s1 = StudyLocationFactory() + with transaction.atomic(), self.assertRaises(IntegrityError): + StudyLocationFactory(site=s1.site, name=s1.name) + s3 = StudyLocationFactory() + self.assertTrue(isinstance(s3, StudyLocation)) + + +class StorageLocationTestCase(TestCase): + def test_creation(self): + s = StorageLocationFactory() + self.assertTrue(isinstance(s, StorageLocation)) + self.assertEqual(s.__str__(), s.code) + + +