def setUp(self):
     self.maxDiff = None
     user_details = {
         'username': '******',
         'password': '******',
     }
     self.user = User.objects.create_superuser(email='*****@*****.**',
                                               **user_details)
     self.org = Organization.objects.create()
     OrganizationUser.objects.create(user=self.user, organization=self.org)
     self.audit_log_factory = FakePropertyAuditLogFactory(
         organization=self.org, user=self.user)
     self.property_factory = FakePropertyFactory(organization=self.org)
     self.property_state_factory = FakePropertyStateFactory(
         organization=self.org)
     self.property_view_factory = FakePropertyViewFactory(
         organization=self.org, user=self.user)
     self.ga_factory = FakeGreenAssessmentFactory(organization=self.org)
     self.gap_factory = FakeGreenAssessmentPropertyFactory(
         organization=self.org, user=self.user)
     self.label_factory = FakeStatusLabelFactory(organization=self.org)
     self.assessment = self.ga_factory.get_green_assessment()
     self.property_view = self.property_view_factory.get_property_view()
     self.gap_data = {
         'source': 'test',
         'status': 'complete',
         'status_date': datetime.date(2017, 0o1, 0o1),
         'metric': 5,
         'version': '0.1',
         'date': datetime.date(2016, 0o1, 0o1),
         'eligibility': True,
         'assessment': self.assessment,
         'view': self.property_view,
     }
     self.urls = ['http://example.com', 'http://example.org']
 def setUp(self):
     self.maxDiff = None
     user_details = {
         'username': '******',
         'password': '******',
     }
     self.user = User.objects.create_superuser(email='*****@*****.**',
                                               **user_details)
     self.org, _, _ = create_organization(self.user)
     self.property_view_factory = FakePropertyViewFactory(
         organization=self.org, user=self.user)
     self.ga_factory = FakeGreenAssessmentFactory(organization=self.org)
     self.gap_factory = FakeGreenAssessmentPropertyFactory(
         organization=self.org, user=self.user)
     self.assessment = self.ga_factory.get_green_assessment()
     self.property_view = self.property_view_factory.get_property_view()
     self.data = {
         'source': 'test',
         'status': 'complete',
         'status_date': '2017-01-01',
         'metric': 5,
         'version': '0.1',
         'date': '2016-01-01',
         'eligibility': True,
         'assessment': self.assessment,
         'view': self.property_view,
     }
     self.urls = ['http://example.com', 'http://example.org']
示例#3
0
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
            'email': '*****@*****.**',
        }
        self.user = User.objects.create_superuser(**user_details)
        self.org = Organization.objects.create()
        OrganizationUser.objects.create(user=self.user, organization=self.org)

        # Fake Factories
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org)
        self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org)
        self.note_factory = FakeNoteFactory(organization=self.org,
                                            user=self.user)

        self.client.login(**user_details)

        # create a property view with some notes
        self.pv = self.property_view_factory.get_property_view(
            organization=self.org)
        self.note1 = self.note_factory.get_note()
        self.note2 = self.note_factory.get_log_note()

        self.pv.notes.add(self.note1)
        self.pv.notes.add(self.note2)

        # create a taxlot with some views
        self.tl = self.taxlot_view_factory.get_taxlot_view(
            organization=self.org)
        self.note3 = self.note_factory.get_note()
        self.note4 = self.note_factory.get_log_note()
        self.tl.notes.add(self.note3)
        self.tl.notes.add(self.note4)
 def setUp(self):
     self.properties = []
     self.maxDiff = None
     user_details = {
         'username': '******',
         'password': '******',
     }
     self.user = User.objects.create_superuser(email='*****@*****.**', **user_details)
     self.org, _, _ = create_organization(self.user)
     # create a default cycle
     self.cycle = Cycle.objects.filter(organization_id=self.org).first()
     self.property_factory = FakePropertyFactory(
         organization=self.org
     )
     self.property_state_factory = FakePropertyStateFactory(
         organization=self.org
     )
     self.property_view_factory = FakePropertyViewFactory(
         organization=self.org, user=self.user
     )
     self.label_factory = FakeStatusLabelFactory(
         organization=self.org
     )
     self.property_view = self.property_view_factory.get_property_view()
     self.urls = ['http://example.com', 'http://example.org']
     self.client.login(**user_details)
 def setUp(self):
     self.maxDiff = None
     user_details = {
         'username': '******',
         'password': '******',
     }
     self.user = User.objects.create_superuser(email='*****@*****.**',
                                               **user_details)
     self.org = Organization.objects.create()
     OrganizationUser.objects.create(user=self.user, organization=self.org)
     self.audit_log_factory = FakePropertyAuditLogFactory(
         organization=self.org, user=self.user)
     self.cycle_factory = FakeCycleFactory(organization=self.org,
                                           user=self.user)
     self.property_state_factory = FakePropertyStateFactory(
         organization=self.org)
     self.property_view_factory = FakePropertyViewFactory(
         organization=self.org, user=self.user)
     self.ga_factory = FakeGreenAssessmentFactory(organization=self.org)
     self.gap_factory = FakeGreenAssessmentPropertyFactory(
         organization=self.org, user=self.user)
     self.taxlot_property_factory = FakeTaxLotPropertyFactory(
         organization=self.org, user=self.user)
     self.taxlot_state_factory = FakeTaxLotStateFactory(
         organization=self.org)
     self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org,
                                                      user=self.user)
     self.assessment = self.ga_factory.get_green_assessment()
     self.cycle = self.cycle_factory.get_cycle()
     self.property_state = self.property_state_factory.get_property_state()
     self.property_view = self.property_view_factory.get_property_view(
         state=self.property_state, cycle=self.cycle)
     self.taxlot_state = self.taxlot_state_factory.get_taxlot_state()
     self.taxlot_view = self.taxlot_view_factory.get_taxlot_view(
         state=self.taxlot_state, cycle=self.cycle)
     self.audit_log = self.audit_log_factory.get_property_audit_log(
         state=self.property_state,
         view=self.property_view,
         record_type=AUDIT_USER_EDIT,
         description=json.dumps(['a', 'b']))
     self.audit_log2 = self.audit_log_factory.get_property_audit_log(
         view=self.property_view)
     self.gap_data = {
         'source': 'test',
         'status': 'complete',
         'status_date': datetime.date(2017, 0o1, 0o1),
         'metric': 5,
         'version': '0.1',
         'date': datetime.date(2016, 0o1, 0o1),
         'eligibility': True,
         'assessment': self.assessment,
         'view': self.property_view,
     }
     self.urls = ['http://example.com', 'http://example.org']
     self.gap = self.gap_factory.get_green_assessment_property(
         **self.gap_data)
     self.serializer = PropertyViewAsStateSerializer(
         instance=self.property_view)
示例#6
0
    def setUp(self):
        self.user = User.objects.create_superuser('*****@*****.**',
                                                  '*****@*****.**',
                                                  'test_pass')
        self.org, _, _ = create_organization(self.user)

        # Fake Factories
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org)
        self.note_factory = FakeNoteFactory(organization=self.org,
                                            user=self.user)
 def setUp(self):
     self.maxDiff = None
     user_details = {
         'username': '******',
         'password': '******',
     }
     self.user = User.objects.create_superuser(email='*****@*****.**',
                                               **user_details)
     self.org, _, _ = create_organization(self.user)
     self.property_view_factory = FakePropertyViewFactory(
         organization=self.org, user=self.user)
示例#8
0
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(
            email='*****@*****.**', **user_details
        )
        self.org, _, _ = create_organization(self.user)
        self.client.login(**user_details)

        self.property_state_factory = FakePropertyStateFactory(organization=self.org)
        self.tax_lot_state_factory = FakeTaxLotStateFactory(organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(organization=self.org)
        self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org)
示例#9
0
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(email='*****@*****.**',
                                                  **user_details)
        self.org = Organization.objects.create()
        OrganizationUser.objects.create(user=self.user, organization=self.org)

        # Fake Factories
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org)
        self.note_factory = FakeNoteFactory(organization=self.org,
                                            user=self.user)
示例#10
0
class TestNotes(TestCase):
    def setUp(self):
        self.user = User.objects.create_superuser('*****@*****.**',
                                                  '*****@*****.**',
                                                  'test_pass')
        self.org, _, _ = create_organization(self.user)

        # Fake Factories
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org)
        self.note_factory = FakeNoteFactory(organization=self.org,
                                            user=self.user)

    def test_note_assignments(self):
        """Make sure that properties can contain notes"""
        pv = self.property_view_factory.get_property_view(
            organization=self.org)
        note1 = self.note_factory.get_note()
        note2 = self.note_factory.get_note()

        pv.notes.add(note1)
        pv.notes.add(note2)

        self.assertTrue(pv)
        self.assertIn(note1, pv.notes.all())
        self.assertIn(note2, pv.notes.all())
示例#11
0
class TestNotes(TestCase):
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(email='*****@*****.**',
                                                  **user_details)
        self.org = Organization.objects.create()
        OrganizationUser.objects.create(user=self.user, organization=self.org)

        # Fake Factories
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org)
        self.note_factory = FakeNoteFactory(organization=self.org,
                                            user=self.user)

    def test_note_assignments(self):
        """Make sure that properties can contain notes"""
        pv = self.property_view_factory.get_property_view(
            organization=self.org)
        note1 = self.note_factory.get_note()
        note2 = self.note_factory.get_note()

        pv.notes.add(note1)
        pv.notes.add(note2)

        self.assertTrue(pv)
        self.assertIn(note1, pv.notes.all())
        self.assertIn(note2, pv.notes.all())
示例#12
0
 def setUp(self):
     user_details = {
         'username': '******',
         'password': '******',
         'email': '*****@*****.**'
     }
     self.user = User.objects.create_superuser(**user_details)
     self.org, self.org_user, _ = create_organization(self.user)
     self.column_factory = FakeColumnFactory(organization=self.org)
     self.cycle_factory = FakeCycleFactory(organization=self.org, user=self.user)
     self.property_factory = FakePropertyFactory(organization=self.org)
     self.property_state_factory = FakePropertyStateFactory(organization=self.org)
     self.property_view_factory = FakePropertyViewFactory(organization=self.org)
     self.taxlot_state_factory = FakeTaxLotStateFactory(organization=self.org)
     self.cycle = self.cycle_factory.get_cycle(
         start=datetime(2010, 10, 10, tzinfo=timezone.get_current_timezone()))
     self.client.login(**user_details)
示例#13
0
    def setUp(self):
        selfvars = self.set_up(ASSESSED_RAW)
        self.user, self.org, self.import_file, self.import_record, self.cycle = selfvars

        self.property_factory = FakePropertyFactory(organization=self.org)
        self.property_state_factory = FakePropertyStateFactory(
            organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org)
示例#14
0
    def test_labels_inventory_specific_filter_endpoint_provides_IDs_for_records_where_label_is_applied(self):
        user = User.objects.create_superuser(
            email='*****@*****.**',
            username='******',
            password='******',
        )
        organization_a, _, _ = create_organization(user, "test-organization-a")

        # Ensures that at least a single label exists to ensure that we are not
        # relying on auto-creation of labels for this test to pass.
        new_label = Label.objects.create(
            color="red",
            name="test_label-a",
            super_organization=organization_a,
        )

        # Create 2 properties and 2 tax lots. Then, apply that label to one of each
        property_view_factory = FakePropertyViewFactory(organization=organization_a, user=user)
        p_view_1 = property_view_factory.get_property_view()
        p_view_1.labels.add(new_label)
        property_view_factory.get_property_view()

        taxlot_view_factory = FakeTaxLotViewFactory(organization=organization_a, user=user)
        tl_view_1 = taxlot_view_factory.get_taxlot_view()
        tl_view_1.labels.add(new_label)
        taxlot_view_factory.get_taxlot_view()

        client = APIClient()
        client.login(username=user.username, password='******')

        url = reverse('api:v3:properties-labels')
        response_a = client.post(url + '?organization_id={}'.format(organization_a.pk))
        data = json.loads(response_a.content)

        for label in data:
            if label.get('name') != 'test_label-a':
                self.assertCountEqual(label.get('is_applied'), [])
            else:
                self.assertCountEqual(label.get('is_applied'), [p_view_1.id])
示例#15
0
    def test_task_create_analysis_property_views_creates_messages_for_failed_property_views(
            self):
        # Setup
        property_view = (FakePropertyViewFactory(
            organization=self.org, user=self.user).get_property_view())
        bogus_property_view_id = -1
        property_view_ids = [bogus_property_view_id, property_view.id]

        # Act
        task_create_analysis_property_views(self.analysis.id,
                                            property_view_ids)

        # Assert
        # a message for the bad property view should have been created
        message = AnalysisMessage.objects.get(analysis=self.analysis)
        self.assertTrue(
            f'Failed to copy property data for PropertyView ID {bogus_property_view_id}'
            in message.user_message)
示例#16
0
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
            'email': '*****@*****.**',
            'first_name': 'Test',
            'last_name': 'User',
        }
        self.user = User.objects.create_user(**user_details)
        self.org_a, _, _ = create_organization(self.user)
        self.org_b, _, _ = create_organization(self.user)

        cycle_a = FakeCycleFactory(organization=self.org_a, user=self.user).get_cycle(name="Cycle Org A")
        cycle_b = FakeCycleFactory(organization=self.org_b, user=self.user).get_cycle(name="Cycle Org B")

        self.analysis_a = (
            FakeAnalysisFactory(organization=self.org_a, user=self.user).get_analysis(
                name='Quite neat',
                service=Analysis.BSYNCR,
            )
        )

        view_factory_a = FakePropertyViewFactory(cycle=cycle_a, organization=self.org_a, user=self.user)
        self.property_views_a = [
            view_factory_a.get_property_view(
                # override unitted fields so that hashes are correct
                site_eui=ureg.Quantity(
                    float(view_factory_a.fake.random_int(min=50, max=600)),
                    "kilobtu / foot ** 2 / year"
                ),
                gross_floor_area=ureg.Quantity(
                    float(view_factory_a.fake.random_number(digits=6)),
                    "foot ** 2"
                ),
            )
            for i in range(2)]

        view_factory_b = FakePropertyViewFactory(cycle=cycle_b, organization=self.org_b, user=self.user)
        self.property_views_b = [
            view_factory_b.get_property_view(
                # override unitted fields so that hashes are correct
                site_eui=ureg.Quantity(
                    float(view_factory_b.fake.random_int(min=50, max=600)),
                    "kilobtu / foot ** 2 / year"
                ),
                gross_floor_area=ureg.Quantity(
                    float(view_factory_b.fake.random_number(digits=6)),
                    "foot ** 2"
                ),
            )
            for i in range(2)]
示例#17
0
文件: test_merge.py 项目: nW-fr/seed
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
            'email': '*****@*****.**'
        }
        self.user = User.objects.create_superuser(**user_details)
        self.org, self.org_user, _ = create_organization(self.user)
        self.cycle_factory = FakeCycleFactory(organization=self.org, user=self.user)
        self.cycle = self.cycle_factory.get_cycle(
            start=datetime(2010, 10, 10, tzinfo=timezone.get_current_timezone())
        )
        self.property_factory = FakePropertyFactory(organization=self.org)
        self.property_state_factory = FakePropertyStateFactory(organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(organization=self.org, cycle=self.cycle)
        self.taxlot_state_factory = FakeTaxLotStateFactory(organization=self.org)
        self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org, cycle=self.cycle)

        # create 10 addresses that are exactly the same
        import_record = ImportRecord.objects.create(super_organization=self.org)
        self.import_file = ImportFile.objects.create(
            import_record=import_record,
            cycle=self.cycle,
        )
class TestTaxLotProperty(TestCase):
    """Tests for exporting data to various formats."""

    def setUp(self):
        self.properties = []
        self.maxDiff = None
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(email='*****@*****.**', **user_details)
        self.org, _, _ = create_organization(self.user)
        # create a default cycle
        self.cycle = Cycle.objects.filter(organization_id=self.org).first()
        self.property_factory = FakePropertyFactory(
            organization=self.org
        )
        self.property_state_factory = FakePropertyStateFactory(
            organization=self.org
        )
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org, user=self.user
        )
        self.label_factory = FakeStatusLabelFactory(
            organization=self.org
        )
        self.property_view = self.property_view_factory.get_property_view()
        self.urls = ['http://example.com', 'http://example.org']
        self.client.login(**user_details)

    def test_tax_lot_property_get_related(self):
        """Test to make sure get_related returns the fields"""
        for i in range(50):
            p = self.property_view_factory.get_property_view()
            self.properties.append(p.id)

        qs_filter = {"pk__in": self.properties}
        qs = PropertyView.objects.filter(**qs_filter)

        columns = [
            'address_line_1', 'generation_date', 'energy_alerts', 'space_alerts',
            'building_count', 'owner', 'source_eui', 'jurisdiction_tax_lot_id',
            'city', 'district', 'site_eui', 'building_certification', 'modified', 'match_type',
            'source_eui_weather_normalized', 'id', 'property_name', 'conditioned_floor_area',
            'pm_property_id', 'use_description', 'source_type', 'year_built', 'release_date',
            'gross_floor_area', 'owner_city_state', 'owner_telephone', 'recent_sale_date',
        ]
        columns_from_database = Column.retrieve_all(self.org.id, 'property', False)
        data = TaxLotProperty.get_related(qs, columns, columns_from_database)

        self.assertEqual(len(data), 50)
        self.assertEqual(len(data[0]['related']), 0)

    def test_csv_export(self):
        """Test to make sure get_related returns the fields"""
        for i in range(50):
            p = self.property_view_factory.get_property_view()
            self.properties.append(p.id)

        columns = []
        for c in Column.retrieve_all(self.org.id, 'property', False):
            columns.append(c['name'])

        # call the API
        url = reverse_lazy('api:v2.1:tax_lot_properties-csv')
        response = self.client.post(
            url + '?{}={}&{}={}&{}={}'.format(
                'organization_id', self.org.pk,
                'cycle_id', self.cycle,
                'inventory_type', 'properties'
            ),
            data=json.dumps({'columns': columns}),
            content_type='application/json'
        )

        # parse the content as array
        data = response.content.decode('utf-8').split('\n')

        self.assertTrue('Address Line 1' in data[0].split(','))
        self.assertTrue('Property Labels\r' in data[0].split(','))

        self.assertEqual(len(data), 53)
        # last row should be blank
        self.assertEqual(data[52], '')

    def tearDown(self):
        for x in self.properties:
            PropertyView.objects.get(pk=x).delete()
示例#19
0
class StateFieldsTest(TestCase):
    """Tests that our logic for constructing cleaners works."""
    def setUp(self):
        self.maxDiff = None
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(email='*****@*****.**',
                                                  **user_details)
        self.org, _, _ = create_organization(self.user)
        self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org, user=self.user)

    def test_get_state_attrs(self):
        # create the column for data_1
        Column.objects.create(
            column_name=u'data_1',
            table_name=u'TaxLotState',
            organization=self.org,
            is_extra_data=True,
        )
        tlv1 = self.taxlot_view_factory.get_taxlot_view(
            extra_data={"data_1": "value_1"})
        tlv2 = self.taxlot_view_factory.get_taxlot_view(
            extra_data={"data_1": "value_2"})

        self.assertEqual(tlv1.state.extra_data['data_1'], 'value_1')
        self.assertEqual(tlv2.state.extra_data['data_1'], 'value_2')

        res = get_state_attrs([tlv1.state, tlv2.state])
        self.assertEqual(res['custom_id_1'], {
            tlv2.state: None,
            tlv1.state: None
        })
        self.assertEqual(res['postal_code'], {
            tlv2.state: tlv2.state.postal_code,
            tlv1.state: tlv1.state.postal_code
        })
        self.assertTrue('data_1' not in res.keys())

    def test_property_state(self):
        self.property_view_factory.get_property_view()
        self.taxlot_view_factory.get_taxlot_view()

        expected = ((u'address_line_1', u'address_line_1'),
                    (u'address_line_2',
                     u'address_line_2'), (u'analysis_end_time',
                                          u'analysis_end_time'),
                    (u'analysis_start_time',
                     u'analysis_start_time'), (u'analysis_state',
                                               u'analysis_state'),
                    (u'analysis_state_message',
                     u'analysis_state_message'), (u'building_certification',
                                                  u'building_certification'),
                    (u'building_count', u'building_count'), (u'city', u'city'),
                    (u'conditioned_floor_area', u'conditioned_floor_area'),
                    (u'custom_id_1', u'custom_id_1'), (u'energy_alerts',
                                                       u'energy_alerts'),
                    (u'energy_score', u'energy_score'), (u'generation_date',
                                                         u'generation_date'),
                    (u'gross_floor_area',
                     u'gross_floor_area'), (u'home_energy_score_id',
                                            u'home_energy_score_id'),
                    (u'jurisdiction_property_id',
                     u'jurisdiction_property_id'), (u'latitude', u'latitude'),
                    (u'longitude',
                     u'longitude'), (u'lot_number',
                                     u'lot_number'), (u'occupied_floor_area',
                                                      u'occupied_floor_area'),
                    (u'owner',
                     u'owner'), (u'owner_address',
                                 u'owner_address'), (u'owner_city_state',
                                                     u'owner_city_state'),
                    (u'owner_email', u'owner_email'), (u'owner_postal_code',
                                                       u'owner_postal_code'),
                    (u'owner_telephone',
                     u'owner_telephone'), (u'pm_parent_property_id',
                                           u'pm_parent_property_id'),
                    (u'pm_property_id',
                     u'pm_property_id'), (u'postal_code',
                                          u'postal_code'), (u'property_name',
                                                            u'property_name'),
                    (u'property_notes', u'property_notes'), (u'property_type',
                                                             u'property_type'),
                    (u'recent_sale_date',
                     u'recent_sale_date'), (u'release_date',
                                            u'release_date'), (u'site_eui',
                                                               u'site_eui'),
                    (u'site_eui_modeled',
                     u'site_eui_modeled'), (u'site_eui_weather_normalized',
                                            u'site_eui_weather_normalized'),
                    (u'source_eui', u'source_eui'), (u'source_eui_modeled',
                                                     u'source_eui_modeled'),
                    (u'source_eui_weather_normalized',
                     u'source_eui_weather_normalized'), (u'space_alerts',
                                                         u'space_alerts'),
                    (u'state', u'state'), (u'ubid', u'ubid'),
                    (u'use_description',
                     u'use_description'), (u'year_built',
                                           u'year_built'), (u'year_ending',
                                                            u'year_ending'))

        result = get_state_to_state_tuple('PropertyState')
        self.assertSequenceEqual(expected, result)

    def test_taxlot_state(self):
        expected = ((u'address_line_1', u'address_line_1'),
                    (u'address_line_2', u'address_line_2'), (u'block_number',
                                                             u'block_number'),
                    (u'city', u'city'), (u'custom_id_1', u'custom_id_1'),
                    (u'district', u'district'), (u'jurisdiction_tax_lot_id',
                                                 u'jurisdiction_tax_lot_id'),
                    (u'number_properties', u'number_properties'),
                    (u'postal_code', u'postal_code'), (u'state', u'state'))
        result = get_state_to_state_tuple(u'TaxLotState')
        self.assertSequenceEqual(expected, result)
class TestFields(DeleteModelsTestCase):
    def get_date_string(self, dtobj):
        """Get YY-MM-DD string"""
        return "{}-{}-{}".format(dtobj.year, dtobj.month, dtobj.day)

    def setUp(self):
        self.maxDiff = None
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(email='*****@*****.**',
                                                  **user_details)
        self.org, _, _ = create_organization(self.user)
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org, user=self.user)

    def test_url_field(self):
        """Test GreenAssessmentURLField"""
        field = GreenAssessmentURLField()
        url1 = mock.MagicMock()
        url1.url = 'http://example.com'
        url1.description = 'example.com'
        url2 = mock.MagicMock()
        url2.url = 'http://example.org'
        url2.description = 'example.org'
        mock_obj = mock.MagicMock()
        mock_obj.all.return_value = [url1, url2]
        expected = [('http://example.com', 'example.com'),
                    ('http://example.org', 'example.org')]
        result = field.to_representation(mock_obj)
        self.assertEqual(expected, result)

    def test_property_view_field(self):
        """Test PropertyViewField"""
        property_view = self.property_view_factory.get_property_view()
        state = property_view.state
        cycle = OrderedDict(
            (('id', property_view.cycle.id),
             ('start', self.get_date_string(property_view.cycle.start)),
             ('end', self.get_date_string(property_view.cycle.end))))
        expected = OrderedDict(
            (('id', property_view.pk), ('address_line_1',
                                        titlecase(state.normalized_address)),
             ('address_line_2', state.address_line_2), ('city', state.city),
             ('state', state.state), ('postal_code', state.postal_code),
             ('property', property_view.property.id), ('cycle', cycle)))

        field = PropertyViewField(read_only=True)
        result = field.to_representation(property_view)
        self.assertEqual(expected, result)

    def test_validity_duration_field_to_representation(self):
        """Test ValidityDurationField.to_representation()"""
        ga_factory = FakeGreenAssessmentFactory(organization=self.org)
        green_assessment = ga_factory.get_green_assessment(
            validity_duration=365)
        field = ValidityDurationField()
        result = field.to_representation(green_assessment.validity_duration)
        self.assertEqual(result, 365)

    def test_validity_duration_field_to_internal_value(self):
        """Test ValidityDurationField.to_internal_value()"""
        field = ValidityDurationField()
        result = field.to_internal_value(365)
        expected = datetime.timedelta(365)
        self.assertEqual(result, expected)
        result = field.to_internal_value('365')
        self.assertEqual(result, expected)
        result = field.to_internal_value(None)
        expected = None
        self.assertEqual(result, expected)
        self.assertRaises(ValidationError, field.to_internal_value, 1.54)
        self.assertRaises(ValidationError, field.to_internal_value, 'ten')
        self.assertRaises(ValidationError, field.to_internal_value, 0)
        self.assertRaises(ValidationError, field.to_internal_value, -10)
示例#21
0
class StateFieldsTest(TestCase):
    """Tests that our logic for constructing cleaners works."""

    def setUp(self):
        self.maxDiff = None
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(
            email='*****@*****.**', **user_details
        )
        self.org, _, _ = create_organization(self.user)
        self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(organization=self.org, user=self.user)

    def test_get_state_attrs(self):
        # create the column for data_1
        Column.objects.create(
            column_name='data_1',
            table_name='TaxLotState',
            organization=self.org,
            is_extra_data=True,
        )
        tlv1 = self.taxlot_view_factory.get_taxlot_view(extra_data={"data_1": "value_1"})
        tlv2 = self.taxlot_view_factory.get_taxlot_view(extra_data={"data_1": "value_2"})

        self.assertEqual(tlv1.state.extra_data['data_1'], 'value_1')
        self.assertEqual(tlv2.state.extra_data['data_1'], 'value_2')

        res = get_state_attrs([tlv1.state, tlv2.state])
        self.assertEqual(res['custom_id_1'], {tlv2.state: None, tlv1.state: None})
        self.assertEqual(res['postal_code'],
                         {tlv2.state: tlv2.state.postal_code, tlv1.state: tlv1.state.postal_code})
        self.assertTrue('data_1' not in res)

    def test_property_state(self):
        self.property_view_factory.get_property_view()
        self.taxlot_view_factory.get_taxlot_view()

        expected = (('address_line_1', 'address_line_1'),
                    ('address_line_2', 'address_line_2'),
                    ('analysis_end_time', 'analysis_end_time'),
                    ('analysis_start_time', 'analysis_start_time'),
                    ('analysis_state_message', 'analysis_state_message'),
                    ('building_certification', 'building_certification'),
                    ('building_count', 'building_count'),
                    ('city', 'city'),
                    ('conditioned_floor_area', 'conditioned_floor_area'),
                    ('custom_id_1', 'custom_id_1'),
                    ('energy_alerts', 'energy_alerts'),
                    ('energy_score', 'energy_score'),
                    ('generation_date', 'generation_date'),
                    ('geocoding_confidence', 'geocoding_confidence'),
                    ('gross_floor_area', 'gross_floor_area'),
                    ('home_energy_score_id', 'home_energy_score_id'),
                    ('jurisdiction_property_id', 'jurisdiction_property_id'),
                    ('latitude', 'latitude'),
                    ('long_lat', 'long_lat'),
                    ('longitude', 'longitude'),
                    ('lot_number', 'lot_number'),
                    ('occupied_floor_area', 'occupied_floor_area'),
                    ('owner', 'owner'),
                    ('owner_address', 'owner_address'),
                    ('owner_city_state', 'owner_city_state'),
                    ('owner_email', 'owner_email'),
                    ('owner_postal_code', 'owner_postal_code'),
                    ('owner_telephone', 'owner_telephone'),
                    ('pm_parent_property_id', 'pm_parent_property_id'),
                    ('pm_property_id', 'pm_property_id'),
                    ('postal_code', 'postal_code'),
                    ('property_footprint', 'property_footprint'),
                    ('property_name', 'property_name'),
                    ('property_notes', 'property_notes'),
                    ('property_type', 'property_type'),
                    ('recent_sale_date', 'recent_sale_date'),
                    ('release_date', 'release_date'),
                    ('site_eui', 'site_eui'),
                    ('site_eui_modeled', 'site_eui_modeled'),
                    ('site_eui_weather_normalized', 'site_eui_weather_normalized'),
                    ('source_eui', 'source_eui'),
                    ('source_eui_modeled', 'source_eui_modeled'),
                    ('source_eui_weather_normalized', 'source_eui_weather_normalized'),
                    ('space_alerts', 'space_alerts'),
                    ('state', 'state'),
                    ('ubid', 'ubid'),
                    ('use_description', 'use_description'),
                    ('year_built', 'year_built'),
                    ('year_ending', 'year_ending'))

        result = get_state_to_state_tuple('PropertyState')
        self.assertSequenceEqual(expected, result)

    def test_taxlot_state(self):
        expected = (
            ('address_line_1', 'address_line_1'),
            ('address_line_2', 'address_line_2'),
            ('block_number', 'block_number'),
            ('city', 'city'),
            ('custom_id_1', 'custom_id_1'),
            ('district', 'district'),
            ('geocoding_confidence', 'geocoding_confidence'),
            ('jurisdiction_tax_lot_id', 'jurisdiction_tax_lot_id'),
            ('latitude', 'latitude'),
            ('long_lat', 'long_lat'),
            ('longitude', 'longitude'),
            ('number_properties', 'number_properties'),
            ('postal_code', 'postal_code'),
            ('state', 'state'),
            ('taxlot_footprint', 'taxlot_footprint'),
            ('ulid', 'ulid'))
        result = get_state_to_state_tuple('TaxLotState')
        self.assertSequenceEqual(expected, result)

    def test_merge_state_favor_existing(self):
        pv1 = self.property_view_factory.get_property_view(
            address_line_1='original_address', address_line_2='orig',
            extra_data={'field_1': 'orig_value'}
        )
        pv2 = self.property_view_factory.get_property_view(
            address_line_1='new_address', address_line_2='new',
            extra_data={'field_1': 'new_value'}
        )

        # Do not set priority for address_line_2 to make sure that it chooses t
        column_priorities = {
            'address_line_1': 'Favor Existing', 'extra_data': {'field_1': 'Favor Existing'}
        }

        result = merging.merge_state(pv1.state, pv1.state, pv2.state, column_priorities)
        self.assertEqual(result.address_line_1, 'original_address')
        self.assertEqual(result.address_line_2, 'new')
        self.assertEqual(result.extra_data['field_1'], 'orig_value')

    def test_merge_geocoding_results_no_merge_protection(self):
        """
        When merging records that have geocoding results, if none of the
        geocoding results columns have merge protection but both records have
        some form of geocoding results, completely "take" the results from
        the "new" state.
        """
        pv1 = self.property_view_factory.get_property_view(
            address_line_1='original_address',
            latitude=39.765251,
            longitude=-104.986138,
            geocoding_confidence='High (P1AAA)',
            long_lat='POINT (-104.986138 39.765251)',
        )
        pv2 = self.property_view_factory.get_property_view(
            address_line_1='new_address',
            geocoding_confidence='Low - check address (Z1XAA)',
        )

        # Column priorities while purposely leaving out long_lat (as it's not available to users)
        column_priorities = {
            'address_line_1': 'Favor New',
            'geocoding_confidence': 'Favor New',
            'latitude': 'Favor New',
            'longitude': 'Favor New',
            'extra_data': {}
        }

        result = merging.merge_state(pv1.state, pv1.state, pv2.state, column_priorities)
        self.assertEqual(result.geocoding_confidence, 'Low - check address (Z1XAA)')
        self.assertIsNone(result.latitude)
        self.assertIsNone(result.longitude)
        self.assertIsNone(result.long_lat)

    def test_merge_geocoding_results_with_merge_protection(self):
        """
        When merging records that have geocoding results, if any of the
        geocoding results columns have merge protection, and both records have
        some form of geocoding results, completely "take" the results from
        the "existing" state.
        """
        pv1 = self.property_view_factory.get_property_view(
            address_line_1='original_address',
            latitude=39.765251,
            longitude=-104.986138,
            geocoding_confidence='High (P1AAA)',
            long_lat='POINT (-104.986138 39.765251)',
        )
        pv2 = self.property_view_factory.get_property_view(
            address_line_1='new_address',
            geocoding_confidence='Low - check address (Z1XAA)',
        )

        # Column priorities while purposely leaving out long_lat (as it's not available to users)
        column_priorities = {
            'address_line_1': 'Favor New',
            'geocoding_confidence': 'Favor Existing',
            'latitude': 'Favor New',
            'longitude': 'Favor New',
            'extra_data': {}
        }

        result = merging.merge_state(pv1.state, pv1.state, pv2.state, column_priorities)
        self.assertEqual(result.geocoding_confidence, 'High (P1AAA)')
        self.assertEqual(result.latitude, 39.765251)
        self.assertEqual(result.longitude, -104.986138)
        self.assertEqual(long_lat_wkt(result), 'POINT (-104.986138 39.765251)')

    def test_merge_geocoding_results_unpopulated_existing_state_ignores_merge_protections(self):
        """
        When merging records with geocoding columns that have merge protection
        active, if only one record has geocoding results, always take the
        geocoding results from the one record, regardless of merge
        protection settings.
        """
        pv1 = self.property_view_factory.get_property_view(
            address_line_1='original_address',
        )
        pv2 = self.property_view_factory.get_property_view(
            address_line_1='new_address',
            geocoding_confidence='Low - check address (Z1XAA)',
        )

        # Column priorities while purposely leaving out long_lat (as it's not available to users)
        column_priorities = {
            'address_line_1': 'Favor New',
            'geocoding_confidence': 'Favor Existing',
            'latitude': 'Favor Existing',
            'longitude': 'Favor Existing',
            'extra_data': {}
        }

        result = merging.merge_state(pv1.state, pv1.state, pv2.state, column_priorities)
        self.assertEqual(result.geocoding_confidence, 'Low - check address (Z1XAA)')
        self.assertIsNone(result.latitude)
        self.assertIsNone(result.longitude)
        self.assertIsNone(result.long_lat)

    def test_merge_geocoding_results_no_merge_protection_unpopulated_existing_state(self):
        """
        When merging records with geocoding columns that have merge protection
        active, if only one record has geocoding results, always take the
        geocoding results from the one record, regardless of merge
        protection settings.
        """
        pv1 = self.property_view_factory.get_property_view(
            address_line_1='original_address',
            geocoding_confidence='Low - check address (Z1XAA)',
        )
        pv2 = self.property_view_factory.get_property_view(
            address_line_1='new_address',
        )

        # Column priorities while purposely leaving out long_lat (as it's not available to users)
        column_priorities = {
            'address_line_1': 'Favor New',
            'geocoding_confidence': 'Favor New',
            'latitude': 'Favor New',
            'longitude': 'Favor New',
            'extra_data': {}
        }

        result = merging.merge_state(pv1.state, pv1.state, pv2.state, column_priorities)
        self.assertEqual(result.geocoding_confidence, 'Low - check address (Z1XAA)')
        self.assertIsNone(result.latitude)
        self.assertIsNone(result.longitude)
        self.assertIsNone(result.long_lat)

    def test_merge_geocoding_ignore_merge_protection(self):
        """
        When merging records with geocoding columns including the
        ignore_merge_protection flag as True always takes the "new" state's
        geocoding results regardless of geocoding columns merge protection setting.
        """
        pv1 = self.property_view_factory.get_property_view(
            address_line_1='original_address',
            geocoding_confidence='Low - check address (Z1XAA)',
        )
        pv2 = self.property_view_factory.get_property_view(
            address_line_1='new_address',
            latitude=39.765251,
            longitude=-104.986138,
            geocoding_confidence='High (P1AAA)',
            long_lat='POINT (-104.986138 39.765251)',
        )

        # Column priorities while purposely leaving out long_lat (as it's not available to users)
        column_priorities = {
            'address_line_1': 'Favor New',
            'geocoding_confidence': 'Favor Existing',
            'latitude': 'Favor New',
            'longitude': 'Favor New',
            'extra_data': {}
        }

        result = merging.merge_state(pv1.state, pv1.state, pv2.state, column_priorities, True)
        self.assertEqual(result.geocoding_confidence, 'High (P1AAA)')
        self.assertEqual(result.latitude, 39.765251)
        self.assertEqual(result.longitude, -104.986138)
        self.assertEqual(long_lat_wkt(result), 'POINT (-104.986138 39.765251)')

    def test_merge_extra_data(self):
        ed1 = {'field_1': 'orig_value_1', 'field_2': 'orig_value_1', 'field_3': 'only_in_ed1'}
        ed2 = {'field_1': 'new_value_1', 'field_2': 'new_value_2', 'field_4': 'only_in_ed2'}

        # this also tests a priority on the new field but with an existing value that doesn't exist
        # in the new data.
        priorities = {'field_1': 'Favor Existing', 'field_3': 'Favor New'}
        result = merging._merge_extra_data(ed1, ed2, priorities, [])
        expected = {
            'field_1': 'orig_value_1',
            'field_2': 'new_value_2',
            'field_3': 'only_in_ed1',
            'field_4': 'only_in_ed2'
        }
        self.assertDictEqual(result, expected)

    def test_recognize_empty_column_setting_allows_empty_values_to_overwrite_nonempty_values(self):
        # create 2 records
        pv1 = self.property_view_factory.get_property_view(
            address_line_1='original_address',
            energy_score=None,
            extra_data={
                'ed_field_1': 'ed_original_value',
                'ed_field_2': None
            }
        )
        pv2 = self.property_view_factory.get_property_view(
            address_line_1=None,
            energy_score=86,
            extra_data={
                'ed_field_1': None,
                'ed_field_2': 'ED eighty-six'
            }
        )

        # Update and create columns with recognize_empty = True
        self.org.column_set.filter(
            table_name='PropertyState',
            column_name__in=['address_line_1', 'energy_score']
        ).update(recognize_empty=True)
        Column.objects.create(
            column_name='ed_field_1',
            table_name='PropertyState',
            organization=self.org,
            is_extra_data=True,
            recognize_empty=True
        )
        Column.objects.create(
            column_name='ed_field_2',
            table_name='PropertyState',
            organization=self.org,
            is_extra_data=True,
            recognize_empty=True
        )

        # Treat pv1.state as "newer"
        result = merging.merge_state(pv2.state, pv2.state, pv1.state, {'extra_data': {}})

        # should be all the values from state 1
        self.assertEqual(result.address_line_1, 'original_address')
        self.assertIsNone(result.energy_score)
        self.assertEqual(result.extra_data['ed_field_1'], 'ed_original_value')
        self.assertIsNone(result.extra_data['ed_field_2'])

    def test_recognize_empty_and_favor_new_column_settings_together(self):
        # create 2 records
        pv1 = self.property_view_factory.get_property_view(
            address_line_1='original_address',
            energy_score=None,
            extra_data={
                'ed_field_1': 'ed_original_value',
                'ed_field_2': None
            }
        )
        pv2 = self.property_view_factory.get_property_view(
            address_line_1=None,
            energy_score=86,
            extra_data={
                'ed_field_1': None,
                'ed_field_2': 'ED eighty-six'
            }
        )

        # Update and create columns with recognize_empty = True
        self.org.column_set.filter(
            table_name='PropertyState',
            column_name__in=['address_line_1', 'energy_score']
        ).update(recognize_empty=True)
        Column.objects.create(
            column_name='ed_field_1',
            table_name='PropertyState',
            organization=self.org,
            is_extra_data=True,
            recognize_empty=True
        )
        Column.objects.create(
            column_name='ed_field_2',
            table_name='PropertyState',
            organization=self.org,
            is_extra_data=True,
            recognize_empty=True
        )

        # Treat pv1.state as "newer" and favor existing for all priorities
        priorities = {
            'address_line_1': 'Favor Existing',
            'energy_score': 'Favor Existing',
            'extra_data': {
                'ed_field_1': 'Favor Existing',
                'ed_field_2': 'Favor Existing'
            }
        }
        result = merging.merge_state(pv2.state, pv2.state, pv1.state, priorities)

        # should be all the values from state 2
        self.assertIsNone(result.address_line_1)
        self.assertEqual(result.energy_score, 86)
        self.assertIsNone(result.extra_data['ed_field_1'])
        self.assertEqual(result.extra_data['ed_field_2'], 'ED eighty-six')
class TestGreenAssessmentPropertySerializer(DeleteModelsTestCase):
    def setUp(self):
        self.maxDiff = None
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(email='*****@*****.**',
                                                  **user_details)
        self.org, _, _ = create_organization(self.user)
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org, user=self.user)
        self.ga_factory = FakeGreenAssessmentFactory(organization=self.org)
        self.gap_factory = FakeGreenAssessmentPropertyFactory(
            organization=self.org, user=self.user)
        self.assessment = self.ga_factory.get_green_assessment()
        self.property_view = self.property_view_factory.get_property_view()
        self.data = {
            'source': 'test',
            'status': 'complete',
            'status_date': '2017-01-01',
            'metric': 5,
            'version': '0.1',
            'date': '2016-01-01',
            'eligibility': True,
            'assessment': self.assessment,
            'view': self.property_view,
        }
        self.urls = ['http://example.com', 'http://example.org']

    @mock.patch('seed.serializers.certification.GreenAssessmentURL')
    def test_create(self, mock_url_model):
        """Test (overridden) create method."""
        serializer = GreenAssessmentPropertySerializer()
        data = self.data.copy()
        data['urls'] = self.urls
        instance = serializer.create(data)
        mock_url_model.objects.bulk_create.assert_called_with([
            mock_url_model(property_assessment=instance,
                           url=url[0],
                           description=url[1]) for url in self.urls
        ])

    @mock.patch('seed.serializers.certification.GreenAssessmentURL')
    def test_update(self, mock_url_model):
        """Test (overridden) update method."""
        data = self.data.copy()
        data['urls'] = self.urls[:1]
        gap = self.gap_factory.get_green_assessment_property(**data)
        serializer = GreenAssessmentPropertySerializer()
        data['urls'] = self.urls[1:]
        instance = serializer.update(gap, data)
        mock_url_model.objects.filter.assert_called_with(
            property_assessment=instance)
        mock_url_model.assert_called_with(url='http://example.org',
                                          property_assessment=gap)

    def test_validate(self):
        """Test (overriden) validate method"""
        serializer = GreenAssessmentPropertySerializer()
        # add context
        mock_request = mock.MagicMock()
        mock_request.user = self.user
        serializer.context = {'request': mock_request}

        # assert raises error if rating and metric supplied
        data = self.data.copy()
        data['rating'] = 'Gold Star'
        with self.assertRaises(ValidationError) as conm:
            serializer.validate(data)
        exception = conm.exception
        expected = "['Only one of metric or rating can be supplied.']"
        self.assertEqual(expected, str(exception))

        # assert raises error if metric is expected
        del data['metric']
        data['rating'] = '5'
        with self.assertRaises(ValidationError) as conm:
            serializer.validate(data)
        exception = conm.exception
        expected = "['{} uses a metric (numeric score).']".format(
            self.assessment.name)
        self.assertEqual(expected, str(exception))

        # assert raises error if metric is of wrong type
        del data['rating']
        data['metric'] = '5 stars'
        with self.assertRaises(ValidationError) as conm:
            serializer.validate(data)
        exception = conm.exception
        expected = "['Metric must be a number.']"
        self.assertEqual(expected, str(exception))

        # assert raises error if rating expected
        self.assessment.is_numeric_score = False
        data['metric'] = 5
        with self.assertRaises(ValidationError) as conm:
            serializer.validate(data)
        exception = conm.exception
        expected = "['{} uses a rating (non-numeric score).']".format(
            self.assessment.name)

        # assert raises error if rating is of wrong type
        del data['metric']
        data['rating'] = 5
        with self.assertRaises(ValidationError) as conm:
            serializer.validate(data)
        exception = conm.exception
        expected = "['Rating must be a string.']"
        self.assertEqual(expected, str(exception))

        # assert converts ints to floats
        self.assessment.is_numeric_score = True
        del data['rating']
        data['metric'] = 5
        result = serializer.validate(data)
        self.assertEqual(result, data)

        # assert raises error if integer expected
        data['metric'] = 3.5
        with self.assertRaises(ValidationError) as conm:
            serializer.validate(data)
        exception = conm.exception
        expected = "['Metric must be an integer.']"
        self.assertEqual(expected, str(exception))

        # assert raises error if assessment missing
        del data['assessment']
        with self.assertRaises(ValidationError) as conm:
            serializer.validate(data)
        exception = conm.exception
        expected = "['Could not find assessment.']"
        self.assertEqual(expected, str(exception))
示例#23
0
class PropertyViewTests(DeleteModelsTestCase):
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
            'email': '*****@*****.**'
        }
        self.user = User.objects.create_superuser(**user_details)
        self.org, self.org_user, _ = create_organization(self.user)
        self.column_factory = FakeColumnFactory(organization=self.org)
        self.cycle_factory = FakeCycleFactory(organization=self.org,
                                              user=self.user)
        self.property_factory = FakePropertyFactory(organization=self.org)
        self.property_state_factory = FakePropertyStateFactory(
            organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org)
        self.taxlot_state_factory = FakeTaxLotStateFactory(
            organization=self.org)
        self.cycle = self.cycle_factory.get_cycle(
            start=datetime(2010, 10, 10, tzinfo=get_current_timezone()))
        self.column_list_factory = FakeColumnListSettingsFactory(
            organization=self.org)
        self.client.login(**user_details)

    def test_get_and_edit_properties(self):
        state = self.property_state_factory.get_property_state()
        prprty = self.property_factory.get_property()
        view = PropertyView.objects.create(property=prprty,
                                           cycle=self.cycle,
                                           state=state)
        params = {
            'organization_id': self.org.pk,
            'page': 1,
            'per_page': 999999999,
            'columns': COLUMNS_TO_SEND,
        }

        url = reverse('api:v2.1:properties-list') + '?cycle_id={}'.format(
            self.cycle.pk)
        response = self.client.get(url, params)
        data = json.loads(response.content)
        self.assertEqual(len(data['properties']), 1)
        result = data['properties'][0]
        self.assertEqual(result['state']['address_line_1'],
                         state.address_line_1)

        db_created_time = result['created']
        db_updated_time = result['updated']
        self.assertTrue(db_created_time is not None)
        self.assertTrue(db_updated_time is not None)

        # update the address
        new_data = {"state": {"address_line_1": "742 Evergreen Terrace"}}
        url = reverse('api:v2:properties-detail', args=[
            view.id
        ]) + '?organization_id={}'.format(self.org.pk)
        response = self.client.put(url,
                                   json.dumps(new_data),
                                   content_type='application/json')
        data = json.loads(response.content)
        self.assertEqual(data['status'], 'success')

        # the above call returns data from the PropertyState, need to get the Property --
        # call the get on the same API to retrieve it
        response = self.client.get(url, content_type='application/json')
        data = json.loads(response.content)
        # make sure the address was updated and that the datetimes were modified
        self.assertEqual(data['status'], 'success')
        self.assertEqual(data['state']['address_line_1'],
                         '742 Evergreen Terrace')
        self.assertEqual(
            datetime.strptime(db_created_time,
                              "%Y-%m-%dT%H:%M:%S.%fZ").replace(microsecond=0),
            datetime.strptime(data['property']['created'],
                              "%Y-%m-%dT%H:%M:%S.%fZ").replace(microsecond=0))
        self.assertGreater(
            datetime.strptime(data['property']['updated'],
                              "%Y-%m-%dT%H:%M:%S.%fZ"),
            datetime.strptime(db_updated_time, "%Y-%m-%dT%H:%M:%S.%fZ"))

    def test_list_properties_with_profile_id(self):
        state = self.property_state_factory.get_property_state(
            extra_data={"field_1": "value_1"})
        prprty = self.property_factory.get_property()
        PropertyView.objects.create(property=prprty,
                                    cycle=self.cycle,
                                    state=state)

        # save all the columns in the state to the database so we can setup column list settings
        Column.save_column_names(state)
        # get the columnlistsetting (default) for all columns
        columnlistsetting = self.column_list_factory.get_columnlistsettings(
            columns=['address_line_1', 'field_1'])

        params = {
            'organization_id': self.org.pk,
            'profile_id': columnlistsetting.id,
        }
        url = reverse('api:v2.1:properties-list') + '?cycle_id={}'.format(
            self.cycle.pk)
        response = self.client.get(url, params)
        data = response.json()
        self.assertEqual(len(data['properties']), 1)
        result = data['properties'][0]
        self.assertEqual(result['state']['address_line_1'],
                         state.address_line_1)
        self.assertEqual(result['state']['extra_data']['field_1'], 'value_1')
        self.assertFalse(result['state'].get('city', None))

    def test_search_identifier(self):
        self.property_view_factory.get_property_view(cycle=self.cycle,
                                                     custom_id_1='123456')
        self.property_view_factory.get_property_view(
            cycle=self.cycle, custom_id_1='987654 Long Street')
        self.property_view_factory.get_property_view(
            cycle=self.cycle, address_line_1='123 Main Street')
        self.property_view_factory.get_property_view(
            cycle=self.cycle,
            address_line_1='Hamilton Road',
            analysis_state=PropertyState.ANALYSIS_STATE_QUEUED)
        self.property_view_factory.get_property_view(
            cycle=self.cycle,
            custom_id_1='long road',
            analysis_state=PropertyState.ANALYSIS_STATE_QUEUED)

        # Typically looks like this
        # http://localhost:8000/api/v2.1/properties/?organization_id=265&cycle=219&identifier=09-IS

        # check for all items
        query_params = "?cycle={}&organization_id={}".format(
            self.cycle.pk, self.org.pk)
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        self.assertEqual(len(results), 5)

        # check for 2 items with 123
        query_params = "?cycle={}&organization_id={}&identifier={}".format(
            self.cycle.pk, self.org.pk, '123')
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        # print out the result of this when there are more than two in an attempt to catch the
        # non-deterministic part of this test
        if len(results) > 2:
            print(results)

        self.assertEqual(len(results), 2)

        # check the analysis states
        query_params = "?cycle={}&organization_id={}&analysis_state={}".format(
            self.cycle.pk, self.org.pk, 'Completed')
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        self.assertEqual(len(results), 0)

        query_params = "?cycle={}&organization_id={}&analysis_state={}".format(
            self.cycle.pk, self.org.pk, 'Not Started')
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        self.assertEqual(len(results), 3)

        query_params = "?cycle={}&organization_id={}&analysis_state={}".format(
            self.cycle.pk, self.org.pk, 'Queued')
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        self.assertEqual(len(results), 2)

        # check the combination of both the identifier and the analysis state
        query_params = "?cycle={}&organization_id={}&identifier={}&analysis_state={}".format(
            self.cycle.pk, self.org.pk, 'Long', 'Queued')
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        self.assertEqual(len(results), 1)

    def test_meters_exist(self):
        # Create a property set with meters
        state_1 = self.property_state_factory.get_property_state()
        property_1 = self.property_factory.get_property()
        PropertyView.objects.create(property=property_1,
                                    cycle=self.cycle,
                                    state=state_1)

        import_record = ImportRecord.objects.create(
            owner=self.user,
            last_modified_by=self.user,
            super_organization=self.org)
        filename = "example-GreenButton-data.xml"
        filepath = os.path.dirname(
            os.path.abspath(__file__)) + "/data/" + filename
        import_file = ImportFile.objects.create(
            import_record=import_record,
            source_type="GreenButton",
            uploaded_filename=filename,
            file=SimpleUploadedFile(name=filename,
                                    content=open(filepath, 'rb').read()),
            cycle=self.cycle,
            matching_results_data={
                "property_id": property_1.id
            }  # this is how target property is specified
        )
        gb_import_url = reverse("api:v2:import_files-save-raw-data",
                                args=[import_file.id])
        gb_import_post_params = {
            'cycle_id': self.cycle.pk,
            'organization_id': self.org.pk,
        }
        self.client.post(gb_import_url, gb_import_post_params)

        # Create a property set without meters
        state_2 = self.property_state_factory.get_property_state()
        property_2 = self.property_factory.get_property()
        PropertyView.objects.create(property=property_2,
                                    cycle=self.cycle,
                                    state=state_2)

        url = reverse('api:v2:properties-meters-exist')

        true_post_params = json.dumps(
            {'inventory_ids': [property_2.pk, property_1.pk]})
        true_result = self.client.post(url,
                                       true_post_params,
                                       content_type='application/json')
        self.assertEqual(b'true', true_result.content)

        false_post_params = json.dumps({'inventory_ids': [property_2.pk]})
        false_result = self.client.post(url,
                                        false_post_params,
                                        content_type='application/json')
        self.assertEqual(b'false', false_result.content)
示例#24
0
class PropertyViewTests(DeleteModelsTestCase):
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
            'email': '*****@*****.**'
        }
        self.user = User.objects.create_superuser(**user_details)
        self.org, self.org_user, _ = create_organization(self.user)
        self.column_factory = FakeColumnFactory(organization=self.org)
        self.cycle_factory = FakeCycleFactory(organization=self.org, user=self.user)
        self.property_factory = FakePropertyFactory(organization=self.org)
        self.property_state_factory = FakePropertyStateFactory(organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(organization=self.org)
        self.taxlot_state_factory = FakeTaxLotStateFactory(organization=self.org)
        self.cycle = self.cycle_factory.get_cycle(
            start=datetime(2010, 10, 10, tzinfo=timezone.get_current_timezone()))
        self.client.login(**user_details)

    def test_get_and_edit_properties(self):
        state = self.property_state_factory.get_property_state()
        prprty = self.property_factory.get_property()
        view = PropertyView.objects.create(
            property=prprty, cycle=self.cycle, state=state
        )
        params = {
            'organization_id': self.org.pk,
            'page': 1,
            'per_page': 999999999,
            'columns': COLUMNS_TO_SEND,
        }

        url = reverse('api:v2.1:properties-list') + '?cycle_id={}'.format(self.cycle.pk)
        response = self.client.get(url, params)
        data = json.loads(response.content)
        self.assertEqual(len(data['properties']), 1)
        result = data['properties'][0]
        self.assertEqual(result['state']['address_line_1'], state.address_line_1)

        db_created_time = result['created']
        db_updated_time = result['updated']
        self.assertTrue(db_created_time is not None)
        self.assertTrue(db_updated_time is not None)

        # update the address
        new_data = {
            "state": {
                "address_line_1": "742 Evergreen Terrace"
            }
        }
        url = reverse('api:v2:properties-detail', args=[view.id]) + '?organization_id={}'.format(self.org.pk)
        response = self.client.put(url, json.dumps(new_data), content_type='application/json')
        data = json.loads(response.content)
        self.assertEqual(data['status'], 'success')

        # the above call returns data from the PropertyState, need to get the Property --
        # call the get on the same API to retrieve it
        response = self.client.get(url, content_type='application/json')
        data = json.loads(response.content)
        # make sure the address was updated and that the datetimes were modified
        self.assertEqual(data['status'], 'success')
        self.assertEqual(data['state']['address_line_1'], '742 Evergreen Terrace')
        self.assertEqual(datetime.strptime(db_created_time, "%Y-%m-%dT%H:%M:%S.%fZ").replace(microsecond=0),
                         datetime.strptime(data['property']['created'], "%Y-%m-%dT%H:%M:%S.%fZ").replace(
                             microsecond=0))
        self.assertGreater(datetime.strptime(data['property']['updated'], "%Y-%m-%dT%H:%M:%S.%fZ"),
                           datetime.strptime(db_updated_time, "%Y-%m-%dT%H:%M:%S.%fZ"))

    def test_search_identifier(self):
        self.property_view_factory.get_property_view(cycle=self.cycle, custom_id_1='123456')
        self.property_view_factory.get_property_view(cycle=self.cycle, custom_id_1='987654 Long Street')
        self.property_view_factory.get_property_view(cycle=self.cycle, address_line_1='123 Main Street')
        self.property_view_factory.get_property_view(cycle=self.cycle, address_line_1='Hamilton Road',
                                                     analysis_state=PropertyState.ANALYSIS_STATE_QUEUED)
        self.property_view_factory.get_property_view(cycle=self.cycle, custom_id_1='long road',
                                                     analysis_state=PropertyState.ANALYSIS_STATE_QUEUED)

        # Typically looks like this
        # http://localhost:8000/api/v2.1/properties/?organization_id=265&cycle=219&identifier=09-IS

        # check for all items
        query_params = "?cycle={}&organization_id={}".format(self.cycle.pk, self.org.pk)
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        self.assertEqual(len(results), 5)

        # check for 2 items with 123
        query_params = "?cycle={}&organization_id={}&identifier={}".format(self.cycle.pk, self.org.pk, '123')
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        # print out the result of this when there are more than two in an attempt to catch the
        # non-deterministic part of this test
        if len(results) > 2:
            print results

        self.assertEqual(len(results), 2)

        # check the analysis states
        query_params = "?cycle={}&organization_id={}&analysis_state={}".format(self.cycle.pk, self.org.pk, 'Completed')
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        self.assertEqual(len(results), 0)

        query_params = "?cycle={}&organization_id={}&analysis_state={}".format(
            self.cycle.pk, self.org.pk, 'Not Started'
        )
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        self.assertEqual(len(results), 3)

        query_params = "?cycle={}&organization_id={}&analysis_state={}".format(
            self.cycle.pk, self.org.pk, 'Queued'
        )
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        self.assertEqual(len(results), 2)

        # check the combination of both the identifier and the analysis state
        query_params = "?cycle={}&organization_id={}&identifier={}&analysis_state={}".format(
            self.cycle.pk, self.org.pk, 'Long', 'Queued'
        )
        url = reverse('api:v2.1:properties-list') + query_params
        response = self.client.get(url)
        result = json.loads(response.content)
        self.assertEqual(result['status'], 'success')
        results = result['properties']
        self.assertEqual(len(results), 1)
示例#25
0
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
            'email': '*****@*****.**',
            'first_name': 'Test',
            'last_name': 'User',
        }
        self.user = User.objects.create_user(**user_details)
        self.org, _, _ = create_organization(self.user)

        property_state = (
            FakePropertyStateFactory(organization=self.org).get_property_state(
                # fields required for analysis
                latitude=39.76550841416409,
                longitude=-104.97855661401148))
        self.analysis_property_view = (
            FakeAnalysisPropertyViewFactory(
                organization=self.org,
                user=self.user).get_analysis_property_view(
                    property_state=property_state,
                    # analysis args
                    name='Quite neat',
                    service=Analysis.BSYNCR,
                ))

        self.meter = Meter.objects.create(
            property=self.analysis_property_view.property,
            source=Meter.PORTFOLIO_MANAGER,
            source_id="Source ID",
            type=Meter.ELECTRICITY_GRID,
        )
        tz_obj = timezone(TIME_ZONE)
        self.meter_reading = MeterReading.objects.create(
            meter=self.meter,
            start_time=make_aware(datetime(2018, 1, 1, 0, 0, 0),
                                  timezone=tz_obj),
            end_time=make_aware(datetime(2018, 1, 2, 0, 0, 0),
                                timezone=tz_obj),
            reading=12345,
            source_unit='kWh',
            conversion_factor=1.00)

        #
        # Setup more properties with linked meters with 12 valid meter readings.
        # These properties, unmodified, should successfully run thorugh the bsyncr pipeline
        #
        property_view_factory = FakePropertyViewFactory(organization=self.org)
        self.good_property_views = []
        self.num_good_property_views = 3
        for i in range(self.num_good_property_views):
            pv = property_view_factory.get_property_view(
                # fields required for analysis
                latitude=39.76550841416409,
                longitude=-104.97855661401148,
                # override unitted fields so that hashes are correct
                site_eui=ureg.Quantity(
                    float(
                        property_view_factory.fake.random_int(min=50,
                                                              max=600)),
                    "kilobtu / foot ** 2 / year"),
                gross_floor_area=ureg.Quantity(
                    float(property_view_factory.fake.random_number(digits=6)),
                    "foot ** 2"),
            )
            self.good_property_views.append(pv)

        self.analysis_b = (FakeAnalysisFactory(organization=self.org,
                                               user=self.user).get_analysis(
                                                   name='Good Analysis',
                                                   service=Analysis.BSYNCR))

        self.good_meters = []
        for i in range(self.num_good_property_views):
            self.good_meters.append(
                Meter.objects.create(
                    property=self.good_property_views[i].property,
                    source=Meter.PORTFOLIO_MANAGER,
                    source_id="Source ID",
                    type=Meter.ELECTRICITY_GRID,
                ))
            tz_obj = timezone(TIME_ZONE)
            for j in range(1, 13):
                MeterReading.objects.create(
                    meter=self.good_meters[i],
                    start_time=make_aware(datetime(2019, j, 1, 0, 0, 0),
                                          timezone=tz_obj),
                    end_time=make_aware(datetime(2019, j, 28, 0, 0, 0),
                                        timezone=tz_obj),
                    reading=12345,
                    source_unit='kWh',
                    conversion_factor=1.00)
示例#26
0
class TestTaxLotProperty(DataMappingBaseTestCase):
    """Tests for exporting data to various formats."""
    def setUp(self):
        self.properties = []
        self.maxDiff = None
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(email='*****@*****.**',
                                                  **user_details)
        self.org, _, _ = create_organization(self.user)
        # create a default cycle
        self.cycle = Cycle.objects.filter(organization_id=self.org).first()
        self.property_factory = FakePropertyFactory(organization=self.org)
        self.property_state_factory = FakePropertyStateFactory(
            organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org, user=self.user)
        self.label_factory = FakeStatusLabelFactory(organization=self.org)
        self.property_view = self.property_view_factory.get_property_view()
        self.urls = ['http://example.com', 'http://example.org']
        self.client.login(**user_details)

    def test_tax_lot_property_get_related(self):
        """Test to make sure get_related returns the fields"""
        for i in range(50):
            p = self.property_view_factory.get_property_view()
            self.properties.append(p.id)

        qs_filter = {"pk__in": self.properties}
        qs = PropertyView.objects.filter(**qs_filter)

        columns = [
            'address_line_1',
            'generation_date',
            'energy_alerts',
            'space_alerts',
            'building_count',
            'owner',
            'source_eui',
            'jurisdiction_tax_lot_id',
            'city',
            'district',
            'site_eui',
            'building_certification',
            'modified',
            'match_type',
            'source_eui_weather_normalized',
            'id',
            'property_name',
            'conditioned_floor_area',
            'pm_property_id',
            'use_description',
            'source_type',
            'year_built',
            'release_date',
            'gross_floor_area',
            'owner_city_state',
            'owner_telephone',
            'recent_sale_date',
        ]
        columns_from_database = Column.retrieve_all(self.org.id, 'property',
                                                    False)
        data = TaxLotProperty.get_related(qs, columns, columns_from_database)

        self.assertEqual(len(data), 50)
        self.assertEqual(len(data[0]['related']), 0)

    def test_csv_export(self):
        """Test to make sure get_related returns the fields"""
        for i in range(50):
            p = self.property_view_factory.get_property_view()
            self.properties.append(p.id)

        columns = []
        for c in Column.retrieve_all(self.org.id, 'property', False):
            columns.append(c['name'])

        # call the API
        url = reverse_lazy('api:v2.1:tax_lot_properties-export')
        response = self.client.post(url + '?{}={}&{}={}&{}={}'.format(
            'organization_id', self.org.pk, 'cycle_id', self.cycle,
            'inventory_type', 'properties'),
                                    data=json.dumps({
                                        'columns': columns,
                                        'export_type': 'csv'
                                    }),
                                    content_type='application/json')

        # parse the content as array
        data = response.content.decode('utf-8').split('\n')

        self.assertTrue('Address Line 1' in data[0].split(','))
        self.assertTrue('Property Labels\r' in data[0].split(','))

        self.assertEqual(len(data), 53)
        # last row should be blank
        self.assertEqual(data[52], '')

    def test_csv_export_with_notes(self):
        multi_line_note = self.property_view.notes.create(
            name='Manually Created',
            note_type=Note.NOTE,
            text='multi\nline\nnote')
        single_line_note = self.property_view.notes.create(
            name='Manually Created', note_type=Note.NOTE, text='single line')

        self.properties.append(self.property_view.id)

        columns = []
        for c in Column.retrieve_all(self.org.id, 'property', False):
            columns.append(c['name'])

        # call the API
        url = reverse_lazy('api:v2.1:tax_lot_properties-export')
        response = self.client.post(url + '?{}={}&{}={}&{}={}'.format(
            'organization_id', self.org.pk, 'cycle_id', self.cycle,
            'inventory_type', 'properties'),
                                    data=json.dumps({
                                        'columns': columns,
                                        'export_type': 'csv'
                                    }),
                                    content_type='application/json')

        # parse the content as array
        data = response.content.decode('utf-8').split('\r\n')
        notes_string = (multi_line_note.created.astimezone().strftime(
            "%Y-%m-%d %I:%M:%S %p") + "\n" + multi_line_note.text +
                        "\n----------\n" +
                        single_line_note.created.astimezone().strftime(
                            "%Y-%m-%d %I:%M:%S %p") + "\n" +
                        single_line_note.text)

        self.assertEqual(len(data), 3)
        self.assertTrue('Property Notes' in data[0].split(','))

        self.assertTrue(notes_string in data[1])

    def test_xlxs_export(self):
        for i in range(50):
            p = self.property_view_factory.get_property_view()
            self.properties.append(p.id)

        columns = []
        for c in Column.retrieve_all(self.org.id, 'property', False):
            columns.append(c['name'])

        # call the API
        url = reverse_lazy('api:v2.1:tax_lot_properties-export')
        response = self.client.post(url + '?{}={}&{}={}&{}={}'.format(
            'organization_id', self.org.pk, 'cycle_id', self.cycle,
            'inventory_type', 'properties'),
                                    data=json.dumps({
                                        'columns': columns,
                                        'export_type': 'xlsx'
                                    }),
                                    content_type='application/json')

        # parse the content as array
        wb = open_workbook(file_contents=response.content)

        data = [row.value for row in wb.sheet_by_index(0).row(0)]

        self.assertTrue('Address Line 1' in data)
        self.assertTrue('Property Labels' in data)

        self.assertEqual(len([r for r in wb.sheet_by_index(0).get_rows()]), 52)

    def test_json_export(self):
        """Test to make sure get_related returns the fields"""
        for i in range(50):
            p = self.property_view_factory.get_property_view()
            self.properties.append(p.id)

        columns = []
        for c in Column.retrieve_all(self.org.id, 'property', False):
            columns.append(c['name'])

        # call the API
        url = reverse_lazy('api:v2.1:tax_lot_properties-export')
        response = self.client.post(url + '?{}={}&{}={}&{}={}'.format(
            'organization_id', self.org.pk, 'cycle_id', self.cycle,
            'inventory_type', 'properties'),
                                    data=json.dumps({
                                        'columns': columns,
                                        'export_type': 'geojson'
                                    }),
                                    content_type='application/json')

        # parse the content as dictionary
        data = json.loads(response.content)

        first_level_keys = list(data.keys())

        self.assertIn("type", first_level_keys)
        self.assertIn("crs", first_level_keys)
        self.assertIn("features", first_level_keys)

        record_level_keys = list(data['features'][0]['properties'].keys())

        self.assertIn('Address Line 1', record_level_keys)
        self.assertTrue('Gross Floor Area', record_level_keys)

        # ids 52 up to and including 102
        self.assertEqual(len(data['features']), 51)

    def tearDown(self):
        for x in self.properties:
            PropertyView.objects.get(pk=x).delete()
示例#27
0
class TestPropertySerializers(DeleteModelsTestCase):
    def setUp(self):
        self.maxDiff = None
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(email='*****@*****.**',
                                                  **user_details)
        self.org, _, _ = create_organization(self.user)
        self.audit_log_factory = FakePropertyAuditLogFactory(
            organization=self.org, user=self.user)
        self.property_factory = FakePropertyFactory(organization=self.org)
        self.property_state_factory = FakePropertyStateFactory(
            organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org, user=self.user)
        self.ga_factory = FakeGreenAssessmentFactory(organization=self.org)
        self.gap_factory = FakeGreenAssessmentPropertyFactory(
            organization=self.org, user=self.user)
        self.label_factory = FakeStatusLabelFactory(organization=self.org)
        self.assessment = self.ga_factory.get_green_assessment()
        self.property_view = self.property_view_factory.get_property_view()
        self.gap_data = {
            'source': 'test',
            'status': 'complete',
            'status_date': datetime.date(2017, 0o1, 0o1),
            'metric': 5,
            'version': '0.1',
            'date': datetime.date(2016, 0o1, 0o1),
            'eligibility': True,
            'assessment': self.assessment,
            'view': self.property_view,
        }
        self.urls = ['http://example.com', 'http://example.org']

    def test_audit_log_serializer(self):
        """Test to_representation method."""

        # test with AUDIT_USER_CREATE
        audit_log = self.audit_log_factory.get_property_audit_log()
        result = PropertyAuditLogReadOnlySerializer(audit_log).data
        self.assertEqual(result['description'], 'test audit log')
        self.assertEqual(result['date_edited'], audit_log.created.ctime())
        self.assertEqual(result['source'], 'UserCreate')
        self.assertIsNone(result['changed_fields'])
        self.assertEqual(result['state']['city'], 'Boring')

        # test with AUDIT_USER_EDIT
        changed_fields = ['a', 'b', 'c']
        audit_log = self.audit_log_factory.get_property_audit_log(
            record_type=AUDIT_USER_EDIT,
            description=json.dumps(changed_fields))
        result = PropertyAuditLogReadOnlySerializer(audit_log).data
        self.assertEqual(result['description'], 'User edit')
        self.assertEqual(result['source'], 'UserEdit')
        self.assertEqual(result['changed_fields'], changed_fields)

    def test_property_view_list_serializer(self):
        """Test to_representation method."""
        property_view_1 = self.property_view_factory.get_property_view()
        property_view_2 = self.property_view_factory.get_property_view()
        gap1_data = self.gap_data.copy()
        gap2_data = self.gap_data.copy()
        gap1_data['view'] = property_view_1
        gap2_data['view'] = property_view_2
        gap2_data['metric'] = 4
        self.gap_factory.get_green_assessment_property(**gap1_data)
        self.gap_factory.get_green_assessment_property(**gap2_data)
        serializer = PropertyViewListSerializer(child=PropertyViewSerializer())
        result = serializer.to_representation(
            [property_view_1, property_view_2])
        self.assertEqual(result[0]['cycle']['id'], property_view_1.cycle_id)
        self.assertEqual(result[1]['cycle']['id'], property_view_2.cycle_id)
        self.assertEqual(result[0]['state']['id'], property_view_1.state_id)
        self.assertEqual(result[1]['state']['id'], property_view_2.state_id)
        self.assertEqual(result[0]['certifications'][0]['score'], 5)
        self.assertEqual(result[1]['certifications'][0]['score'], 4)
        self.assertEqual(result[0]['certifications'][0]['assessment']['name'],
                         self.assessment.name)
        self.assertEqual(result[1]['certifications'][0]['assessment']['name'],
                         self.assessment.name)

        # with queryset
        serializer = PropertyViewListSerializer(child=PropertyViewSerializer())
        queryset = PropertyView.objects.filter(
            id__in=[property_view_1.id, property_view_2.id]).order_by('id')
        result = serializer.to_representation(queryset)
        self.assertEqual(result[0]['cycle']['id'], property_view_1.cycle_id)
        self.assertEqual(result[1]['cycle']['id'], property_view_2.cycle_id)
        self.assertEqual(result[0]['state']['id'], property_view_1.state_id)
        self.assertEqual(result[1]['state']['id'], property_view_2.state_id)
        self.assertEqual(result[0]['certifications'][0]['score'], 5)
        self.assertEqual(result[1]['certifications'][0]['score'], 4)
        self.assertEqual(result[0]['certifications'][0]['assessment']['name'],
                         self.assessment.name)
        self.assertEqual(result[1]['certifications'][0]['assessment']['name'],
                         self.assessment.name)

    def test_property_list_serializer(self):
        """Test PropertyListSerializer.to_representation"""
        # TODO test to representation
        property1 = self.property_factory.get_property()
        property2 = self.property_factory.get_property()

        expected = [
            OrderedDict([
                ('id', property1.id),
                ('campus', False),
                ('parent_property', None),
            ]),
            OrderedDict([
                ('id', property2.id),
                ('campus', False),
                ('parent_property', None),
            ]),
        ]

        serializer = PropertyListSerializer(child=PropertyMinimalSerializer())
        result = serializer.to_representation([property1, property2])
        self.assertEqual(expected, result)
示例#28
0
class NoteViewTests(TestCase):
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
            'email': '*****@*****.**',
        }
        self.user = User.objects.create_superuser(**user_details)
        self.org = Organization.objects.create()
        OrganizationUser.objects.create(user=self.user, organization=self.org)

        # Fake Factories
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org)
        self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org)
        self.note_factory = FakeNoteFactory(organization=self.org,
                                            user=self.user)

        self.client.login(**user_details)

        # create a property view with some notes
        self.pv = self.property_view_factory.get_property_view(
            organization=self.org)
        self.note1 = self.note_factory.get_note()
        self.note2 = self.note_factory.get_log_note()

        self.pv.notes.add(self.note1)
        self.pv.notes.add(self.note2)

        # create a taxlot with some views
        self.tl = self.taxlot_view_factory.get_taxlot_view(
            organization=self.org)
        self.note3 = self.note_factory.get_note()
        self.note4 = self.note_factory.get_log_note()
        self.tl.notes.add(self.note3)
        self.tl.notes.add(self.note4)

    def test_get_notes_property(self):
        url = reverse('api:v2.1:property-notes-list', args=[self.pv.pk])
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        result = json.loads(response.content)
        results = result['results']
        self.assertEqual(len(results), 2)
        self.assertEqual(results[0]['note_type'], 'Log')
        self.assertEqual(results[0]['user_id'], self.user.pk)

        # most recent log is displayed first
        expected_log_data = {
            u'property_state': [{
                u'field': u'address_line_1',
                u'previous_value': u'123 Main Street',
                u'new_value': u'742 Evergreen Terrace'
            }]
        }
        self.assertEqual(results[0]['log_data'], expected_log_data)
        self.assertEqual(results[1]['note_type'], 'Note')

    def test_create_note_property(self):
        url = reverse('api:v2.1:property-notes-list', args=[self.pv.pk])

        payload = {
            "note_type": "Note",
            "name": "A New Note",
            "text": "This building is much bigger than reported",
        }
        response = self.client.post(url,
                                    data=json.dumps(payload),
                                    content_type='application/json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        result = json.loads(response.content)

        # check that the note was attached to the property
        self.assertEqual(result['note_type'], 'Note')
        self.assertEqual(result['text'], payload['text'])
        self.assertEqual(result['property_view_id'], self.pv.pk)
        self.assertIsNone(result['taxlot_view_id'])
        self.assertEqual(result['organization_id'], self.org.pk)
        self.assertEqual(result['user_id'], self.user.pk)

    def test_create_note_taxlot(self):
        url = reverse('api:v2.1:taxlot-notes-list', args=[self.tl.pk])

        payload = {
            "note_type": "Note",
            "name": "A New Note",
            "text": "The taxlot is not correct",
        }
        response = self.client.post(url,
                                    data=json.dumps(payload),
                                    content_type='application/json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        result = json.loads(response.content)

        # check that the note was attached to the property
        self.assertEqual(result['note_type'], 'Note')
        self.assertEqual(result['text'], payload['text'])
        self.assertIsNone(result['property_view_id'])
        self.assertEqual(result['taxlot_view_id'], self.tl.pk)

    def test_update_note(self):
        url = reverse('api:v2.1:taxlot-notes-detail',
                      args=[self.tl.pk, self.note3.pk])

        payload = {"name": "update, validation should fail"}
        response = self.client.put(url,
                                   data=json.dumps(payload),
                                   content_type='application/json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertEqual(
            json.loads(response.content), {
                "text": ["This field is required."],
                "note_type": ["This field is required."]
            })

        payload = {
            "name": "update",
            "text": "new data with put",
            "note_type": "Note"
        }
        response = self.client.put(url,
                                   data=json.dumps(payload),
                                   content_type='application/json')
        result = json.loads(response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(result['name'], payload['name'])
        self.assertEqual(result['text'], payload['text'])

    def test_patch_note(self):
        url = reverse('api:v2.1:taxlot-notes-detail',
                      args=[self.tl.pk, self.note4.pk])

        payload = {"name": "new note name that is meaningless"}
        response = self.client.patch(url,
                                     data=json.dumps(payload),
                                     content_type='application/json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        result = json.loads(response.content)
        self.assertEqual(result['name'], payload['name'])

    def test_get_detail_and_delete_note(self):
        note5 = self.note_factory.get_note()
        self.pv.notes.add(note5)

        url = reverse('api:v2.1:property-notes-detail',
                      args=[self.pv.pk, note5.pk])
        response = self.client.get(url, content_type='application/json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        result = json.loads(response.content)
        self.assertEqual(result['property_view_id'], self.pv.pk)
        self.assertEqual(result['id'], note5.pk)

        # now delete the note
        response = self.client.delete(url, content_type='application/json')
        # delete returns no content
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

        # note should return nothing now
        response = self.client.get(url, content_type='application/json')
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
示例#29
0
class UbidViewTests(TestCase):
    def setUp(self):
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(email='*****@*****.**',
                                                  **user_details)
        self.org, _, _ = create_organization(self.user)
        self.client.login(**user_details)

        self.property_state_factory = FakePropertyStateFactory(
            organization=self.org)
        self.taxlot_state_factory = FakeTaxLotStateFactory(
            organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org)
        self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org)

    def test_ubid_decode_by_id_endpoint_base(self):
        property_details = self.property_state_factory.get_details()
        property_details['organization_id'] = self.org.id
        property_details['ubid'] = '86HJPCWQ+2VV-1-3-2-3'

        property = PropertyState(**property_details)
        property.save()

        property_view = self.property_view_factory.get_property_view(
            state=property)

        url = reverse(
            'api:v3:ubid-decode-by-ids') + '?organization_id=%s' % self.org.pk
        post_params = {'property_view_ids': [property_view.id]}

        self.client.post(url, post_params)

        refreshed_property = PropertyState.objects.get(pk=property.id)

        property_bounding_box_wkt = (
            "POLYGON ((-87.56021875000002 41.74504999999999, "
            "-87.56021875000002 41.74514999999997, "
            "-87.56043749999996 41.74514999999997, "
            "-87.56043749999996 41.74504999999999, "
            "-87.56021875000002 41.74504999999999))")
        property_centroid_wkt = (
            "POLYGON ((-87.56031249999999 41.74509999999998, "
            "-87.56031249999999 41.74512499999997, "
            "-87.56034374999999 41.74512499999997, "
            "-87.56034374999999 41.74509999999998, "
            "-87.56031249999999 41.74509999999998))")
        self.assertEqual(property_bounding_box_wkt,
                         bounding_box_wkt(refreshed_property))
        self.assertEqual(property_centroid_wkt,
                         centroid_wkt(refreshed_property))

    def test_decode_ubid_results_returns_a_summary_dictionary(self):
        property_none_details = self.property_state_factory.get_details()
        property_none_details["organization_id"] = self.org.id
        property_none = PropertyState(**property_none_details)
        property_none.save()

        property_none_view = self.property_view_factory.get_property_view(
            state=property_none)

        property_correctly_populated_details = self.property_state_factory.get_details(
        )
        property_correctly_populated_details["organization_id"] = self.org.id
        property_correctly_populated_details['ubid'] = '86HJPCWQ+2VV-1-3-2-3'
        property_correctly_populated_details['bounding_box'] = (
            "POLYGON ((-87.56021875000002 41.74504999999999, "
            "-87.56021875000002 41.74514999999997, "
            "-87.56043749999996 41.74514999999997, "
            "-87.56043749999996 41.74504999999999, "
            "-87.56021875000002 41.74504999999999))")
        property_correctly_populated_details['centroid'] = (
            "POLYGON ((-87.56031249999999 41.74509999999998, "
            "-87.56031249999999 41.74512499999997, "
            "-87.56034374999999 41.74512499999997, "
            "-87.56034374999999 41.74509999999998, "
            "-87.56031249999999 41.74509999999998))")
        property_correctly_populated = PropertyState(
            **property_correctly_populated_details)
        property_correctly_populated.save()

        property_correctly_populated_view = self.property_view_factory.get_property_view(
            state=property_correctly_populated)

        property_not_decoded_details = self.property_state_factory.get_details(
        )
        property_not_decoded_details["organization_id"] = self.org.id
        property_not_decoded_details['ubid'] = '86HJPCWQ+2VV-1-3-2-3'
        # bounding_box could be populated from a GeoJSON import
        property_not_decoded_details['bounding_box'] = (
            "POLYGON ((-87.56021875000002 41.74504999999999, "
            "-87.56021875000002 41.74514999999997, "
            "-87.56043749999996 41.74514999999997, "
            "-87.56043749999996 41.74504999999999, "
            "-87.56021875000002 41.74504999999999))")
        property_not_decoded = PropertyState(**property_not_decoded_details)
        property_not_decoded.save()

        property_not_decoded_view = self.property_view_factory.get_property_view(
            state=property_not_decoded)

        url = reverse(
            'api:v3:ubid-decode-results') + '?organization_id=%s' % self.org.pk
        post_params = {
            'property_view_ids': [
                property_none_view.id, property_correctly_populated_view.id,
                property_not_decoded_view.id
            ]
        }

        result = self.client.post(url, post_params)
        result_dict = ast.literal_eval(result.content.decode("utf-8"))

        expectation = {
            "ubid_unpopulated": 1,
            "ubid_successfully_decoded": 1,
            "ubid_not_decoded": 1,
            "ulid_unpopulated": 0,
            "ulid_successfully_decoded": 0,
            "ulid_not_decoded": 0
        }

        self.assertEqual(result_dict, expectation)

    def test_decode_ulid_results_returns_a_summary_dictionary(self):
        taxlot_none_details = self.taxlot_state_factory.get_details()
        taxlot_none_details["organization_id"] = self.org.id
        taxlot_none = TaxLotState(**taxlot_none_details)
        taxlot_none.save()

        taxlot_none_view = self.taxlot_view_factory.get_taxlot_view(
            state=taxlot_none)

        taxlot_correctly_populated_details = self.taxlot_state_factory.get_details(
        )
        taxlot_correctly_populated_details["organization_id"] = self.org.id
        taxlot_correctly_populated_details['ulid'] = '86HJPCWQ+2VV-1-3-2-3'
        taxlot_correctly_populated_details['bounding_box'] = (
            "POLYGON ((-87.56021875000002 41.74504999999999, "
            "-87.56021875000002 41.74514999999997, "
            "-87.56043749999996 41.74514999999997, "
            "-87.56043749999996 41.74504999999999, "
            "-87.56021875000002 41.74504999999999))")
        taxlot_correctly_populated_details['centroid'] = (
            "POLYGON ((-87.56031249999999 41.74509999999998, "
            "-87.56031249999999 41.74512499999997, "
            "-87.56034374999999 41.74512499999997, "
            "-87.56034374999999 41.74509999999998, "
            "-87.56031249999999 41.74509999999998))")
        taxlot_correctly_populated = TaxLotState(
            **taxlot_correctly_populated_details)
        taxlot_correctly_populated.save()

        taxlot_correctly_populated_view = self.taxlot_view_factory.get_taxlot_view(
            state=taxlot_correctly_populated)

        taxlot_not_decoded_details = self.taxlot_state_factory.get_details()
        taxlot_not_decoded_details["organization_id"] = self.org.id
        taxlot_not_decoded_details['ulid'] = '86HJPCWQ+2VV-1-3-2-3'
        # bounding_box could be populated from a GeoJSON import
        taxlot_not_decoded_details['bounding_box'] = (
            "POLYGON ((-87.56021875000002 41.74504999999999, "
            "-87.56021875000002 41.74514999999997, "
            "-87.56043749999996 41.74514999999997, "
            "-87.56043749999996 41.74504999999999, "
            "-87.56021875000002 41.74504999999999))")
        taxlot_not_decoded = TaxLotState(**taxlot_not_decoded_details)
        taxlot_not_decoded.save()

        taxlot_not_decoded_view = self.taxlot_view_factory.get_taxlot_view(
            state=taxlot_not_decoded)

        url = reverse(
            'api:v3:ubid-decode-results') + '?organization_id=%s' % self.org.pk
        post_params = {
            'taxlot_view_ids': [
                taxlot_none_view.id, taxlot_correctly_populated_view.id,
                taxlot_not_decoded_view.id
            ]
        }

        result = self.client.post(url, post_params)
        result_dict = ast.literal_eval(result.content.decode("utf-8"))

        expectation = {
            "ubid_unpopulated": 0,
            "ubid_successfully_decoded": 0,
            "ubid_not_decoded": 0,
            "ulid_unpopulated": 1,
            "ulid_successfully_decoded": 1,
            "ulid_not_decoded": 1
        }

        self.assertEqual(result_dict, expectation)
示例#30
0
class TestPropertyViewAsStateSerializers(DeleteModelsTestCase):
    def setUp(self):
        self.maxDiff = None
        user_details = {
            'username': '******',
            'password': '******',
        }
        self.user = User.objects.create_superuser(email='*****@*****.**',
                                                  **user_details)
        self.org, _, _ = create_organization(self.user)
        self.audit_log_factory = FakePropertyAuditLogFactory(
            organization=self.org, user=self.user)
        self.cycle_factory = FakeCycleFactory(organization=self.org,
                                              user=self.user)
        self.property_state_factory = FakePropertyStateFactory(
            organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(
            organization=self.org, user=self.user)
        self.ga_factory = FakeGreenAssessmentFactory(organization=self.org)
        self.gap_factory = FakeGreenAssessmentPropertyFactory(
            organization=self.org, user=self.user)
        self.taxlot_property_factory = FakeTaxLotPropertyFactory(
            organization=self.org, user=self.user)
        self.taxlot_state_factory = FakeTaxLotStateFactory(
            organization=self.org)
        self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org,
                                                         user=self.user)
        self.assessment = self.ga_factory.get_green_assessment()
        self.cycle = self.cycle_factory.get_cycle()
        self.property_state = self.property_state_factory.get_property_state()
        self.property_view = self.property_view_factory.get_property_view(
            state=self.property_state, cycle=self.cycle)
        self.taxlot_state = self.taxlot_state_factory.get_taxlot_state()
        self.taxlot_view = self.taxlot_view_factory.get_taxlot_view(
            state=self.taxlot_state, cycle=self.cycle)
        self.audit_log = self.audit_log_factory.get_property_audit_log(
            state=self.property_state,
            view=self.property_view,
            record_type=AUDIT_USER_EDIT,
            description=json.dumps(['a', 'b']))
        self.audit_log2 = self.audit_log_factory.get_property_audit_log(
            view=self.property_view)
        self.gap_data = {
            'source': 'test',
            'status': 'complete',
            'status_date': datetime.date(2017, 0o1, 0o1),
            'metric': 5,
            'version': '0.1',
            'date': datetime.date(2016, 0o1, 0o1),
            'eligibility': True,
            'assessment': self.assessment,
            'view': self.property_view,
        }
        self.urls = ['http://example.com', 'http://example.org']
        self.gap = self.gap_factory.get_green_assessment_property(
            **self.gap_data)
        self.serializer = PropertyViewAsStateSerializer(
            instance=self.property_view)

    def test_init(self):
        """Test __init__."""
        expected = PropertyAuditLogReadOnlySerializer(self.audit_log).data

        # for now convert the site_eui to a magnitude to get the test to pass
        # this really needs to be at another level
        data = self.serializer.current
        # data['state']['site_eui'] = data['state']['site_eui'].magnitude
        self.assertEqual(data, expected)

    def test_get_certifications(self):
        """Test get_certifications"""
        expected = [GreenAssessmentPropertyReadOnlySerializer(self.gap).data]
        self.assertEqual(
            self.serializer.get_certifications(self.property_view), expected)

    def test_get_changed_fields(self):
        """Test get_changed_fields"""
        expected = ['a', 'b']
        self.assertEqual(self.serializer.get_changed_fields(None), expected)

    def test_get_date_edited(self):
        """Test get_date_edited"""
        expected = self.audit_log.created.ctime()
        self.assertEqual(self.serializer.get_date_edited(None), expected)

    def test_get_filename(self):
        """Test get_filename"""
        expected = self.audit_log.import_filename
        self.assertEqual(self.serializer.get_filename(None), expected)

    def test_get_history(self):
        """Test get_history"""
        obj = mock.MagicMock()
        obj.state = self.property_state

        data = self.serializer.get_history(obj)
        # Really need to figure out how to get the serializer to save the magnitude correctly.
        # data[0]['state']['site_eui'] = data[0]['state']['site_eui'].magnitude

        expected = [PropertyAuditLogReadOnlySerializer(self.audit_log2).data]
        self.assertEqual(data, expected)

    def test_get_state(self):
        obj = mock.MagicMock()
        obj.state = self.property_state

    def test_get_source(self):
        """Test get_source"""
        expected = self.audit_log.get_record_type_display()
        self.assertEqual(self.serializer.get_source(None), expected)

    def test_get_taxlots(self):
        """Test get_taxlots"""
        self.taxlot_property_factory.get_taxlot_property(
            cycle=self.cycle,
            property_view=self.property_view,
            taxlot_view=self.taxlot_view)
        result = self.serializer.get_taxlots(self.property_view)
        self.assertEqual(result[0]['state']['id'], self.taxlot_state.id)

    @mock.patch('seed.serializers.properties.PropertyView')
    @mock.patch('seed.serializers.properties.PropertyStateWritableSerializer')
    def test_create(self, mock_serializer, mock_pview):
        """Test create"""
        mock_serializer.return_value.is_valid.return_value = True
        mock_serializer.return_value.save.return_value = self.property_state
        mock_pview.objects.create.return_value = self.property_view
        data = {'org_id': 1, 'cycle': 2, 'state': {'test': 3}, 'property': 4}

        serializer = PropertyViewAsStateSerializer()
        serializer.create(data)
        mock_serializer.assert_called_with(data={'test': 3})
        self.assertTrue(mock_serializer.return_value.save.called)
        mock_pview.objects.create.assert_called_with(state=self.property_state,
                                                     cycle_id=2,
                                                     property_id=4,
                                                     org_id=1)

    @mock.patch('seed.serializers.properties.PropertyStateWritableSerializer')
    def test_update_put(self, mock_serializer):
        """Test update with PUT"""
        mock_serializer.return_value.is_valid.return_value = True
        mock_serializer.return_value.save.return_value = self.property_state
        mock_request = mock.MagicMock()
        data = {'org_id': 1, 'cycle': 2, 'state': {'test': 3}, 'property': 4}

        serializer = PropertyViewAsStateSerializer(
            context={'request': mock_request})
        mock_request.METHOD = 'PUT'
        serializer.update(self.property_view, data)
        mock_serializer.assert_called_with(data={'test': 3})
        self.assertTrue(mock_serializer.return_value.save.called)

    @mock.patch('seed.serializers.properties.PropertyStateWritableSerializer')
    def test_update_patch(self, mock_serializer):
        """Test update with PATCH"""
        mock_serializer.return_value.is_valid.return_value = True
        mock_serializer.return_value.save.return_value = self.property_state
        mock_request = mock.MagicMock()
        mock_request.method = 'PATCH'
        data = {'org_id': 1, 'cycle': 2, 'state': {'test': 3}, 'property': 4}
        serializer = PropertyViewAsStateSerializer(
            context={'request': mock_request})
        serializer.update(self.property_view, data)
        mock_serializer.assert_called_with(self.property_state,
                                           data={'test': 3})
        self.assertTrue(mock_serializer.return_value.save.called)