Пример #1
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.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)
Пример #3
0
 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)
Пример #4
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)
Пример #5
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])
Пример #6
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, cycle=self.cycle)
        self.taxlot_state_factory = FakeTaxLotStateFactory(
            organization=self.org)
        self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org,
                                                         cycle=self.cycle)
Пример #7
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.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,
        )
Пример #8
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)
Пример #9
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)
Пример #10
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)
Пример #11
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)
Пример #12
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')
Пример #13
0
class GeocodeViewTests(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.tax_lot_state_factory = FakeTaxLotStateFactory(organization=self.org)
        self.property_view_factory = FakePropertyViewFactory(organization=self.org)
        self.taxlot_view_factory = FakeTaxLotViewFactory(organization=self.org)

    def test_geocode_endpoint_base_with_prepopulated_lat_long_no_api_request(self):
        property_details = self.property_state_factory.get_details()
        property_details['organization_id'] = self.org.id
        property_details['latitude'] = 39.765251
        property_details['longitude'] = -104.986138

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

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

        post_params = {
            'property_view_ids': [property_view.id],
            'taxlot_view_ids': []
        }

        url = reverse('api:v3:geocode-geocode-by-ids') + '?organization_id=%s' % self.org.pk
        self.client.post(url, post_params)

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

        self.assertEqual('POINT (-104.986138 39.765251)', long_lat_wkt(refreshed_property))

    def test_geocode_confidence_summary_returns_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_high_details = self.property_state_factory.get_details()
        property_high_details["organization_id"] = self.org.id
        property_high_details["geocoding_confidence"] = "High (P1AAA)"
        property_high = PropertyState(**property_high_details)
        property_high.save()

        property_high_view = self.property_view_factory.get_property_view(state=property_high)

        property_low_details = self.property_state_factory.get_details()
        property_low_details["organization_id"] = self.org.id
        property_low_details["geocoding_confidence"] = "Low (P1CCC)"
        property_low = PropertyState(**property_low_details)
        property_low.save()

        property_low_view = self.property_view_factory.get_property_view(state=property_low)

        property_manual_details = self.property_state_factory.get_details()
        property_manual_details["organization_id"] = self.org.id
        property_manual_details["geocoding_confidence"] = "Manually geocoded (N/A)"
        property_manual = PropertyState(**property_manual_details)
        property_manual.save()

        property_manual_view = self.property_view_factory.get_property_view(state=property_manual)

        property_missing_details = self.property_state_factory.get_details()
        property_missing_details["organization_id"] = self.org.id
        property_missing_details["geocoding_confidence"] = "Missing address components (N/A)"
        property_missing = PropertyState(**property_missing_details)
        property_missing.save()

        property_missing_view = self.property_view_factory.get_property_view(state=property_missing)

        tax_lot_none_details = self.tax_lot_state_factory.get_details()
        tax_lot_none_details["organization_id"] = self.org.id
        tax_lot_none = TaxLotState(**tax_lot_none_details)
        tax_lot_none.save()

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

        tax_lot_high_details = self.tax_lot_state_factory.get_details()
        tax_lot_high_details["organization_id"] = self.org.id
        tax_lot_high_details["geocoding_confidence"] = "High (P1AAA)"
        tax_lot_high = TaxLotState(**tax_lot_high_details)
        tax_lot_high.save()

        taxlot_high_view = self.taxlot_view_factory.get_taxlot_view(state=tax_lot_high)

        tax_lot_low_details = self.tax_lot_state_factory.get_details()
        tax_lot_low_details["organization_id"] = self.org.id
        tax_lot_low_details["geocoding_confidence"] = "Low (P1CCC)"
        tax_lot_low = TaxLotState(**tax_lot_low_details)
        tax_lot_low.save()

        taxlot_low_view = self.taxlot_view_factory.get_taxlot_view(state=tax_lot_low)

        tax_lot_manual_details = self.tax_lot_state_factory.get_details()
        tax_lot_manual_details["organization_id"] = self.org.id
        tax_lot_manual_details["geocoding_confidence"] = "Manually geocoded (N/A)"
        tax_lot_manual = TaxLotState(**tax_lot_manual_details)
        tax_lot_manual.save()

        taxlot_manual_view = self.taxlot_view_factory.get_taxlot_view(state=tax_lot_manual)

        tax_lot_missing_details = self.tax_lot_state_factory.get_details()
        tax_lot_missing_details["organization_id"] = self.org.id
        tax_lot_missing_details["geocoding_confidence"] = "Missing address components (N/A)"
        tax_lot_missing = TaxLotState(**tax_lot_missing_details)
        tax_lot_missing.save()

        taxlot_missing_view = self.taxlot_view_factory.get_taxlot_view(state=tax_lot_missing)

        url = reverse('api:v3:geocode-confidence-summary')
        post_params = {
            'organization_id': self.org.pk,
            'property_view_ids': [
                property_none_view.id,
                property_high_view.id,
                property_low_view.id,
                property_manual_view.id,
                property_missing_view.id
            ],
            'taxlot_view_ids': [
                taxlot_none_view.id,
                taxlot_high_view.id,
                taxlot_low_view.id,
                taxlot_manual_view.id,
                taxlot_missing_view.id
            ]
        }

        result = self.client.post(url, post_params)
        result_dict = ast.literal_eval(result.content.decode("utf-8"))
        expectation = {
            "properties": {
                "not_geocoded": 1,
                "high_confidence": 1,
                "low_confidence": 1,
                "manual": 1,
                "missing_address_components": 1
            },
            "tax_lots": {
                "not_geocoded": 1,
                "high_confidence": 1,
                "low_confidence": 1,
                "manual": 1,
                "missing_address_components": 1
            }
        }

        self.assertEqual(result_dict, expectation)

    def test_api_key_endpoint_returns_true_or_false_if_org_has_api_key(self):
        url = reverse("api:v3:organizations-geocode-api-key-exists", args=[self.org.pk])
        post_params_false = {'organization_id': self.org.pk}
        false_result = self.client.get(url, post_params_false)

        self.assertEqual(b'false', false_result.content)

        org_with_key, _, _ = create_organization(self.user)
        org_with_key.mapquest_api_key = "somekey"
        org_with_key.save()

        url = reverse("api:v3:organizations-geocode-api-key-exists", args=[org_with_key.id])
        post_params_true = {'organization_id': org_with_key.id}
        true_result = self.client.get(url, post_params_true)

        self.assertEqual(b'true', true_result.content)
Пример #14
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'),
                    ('gross_floor_area',
                     'gross_floor_area'), ('home_energy_score_id',
                                           'home_energy_score_id'),
                    ('jurisdiction_property_id',
                     'jurisdiction_property_id'), ('latitude', 'latitude'),
                    ('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_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'),
                    ('jurisdiction_tax_lot_id', 'jurisdiction_tax_lot_id'),
                    ('number_properties', 'number_properties'),
                    ('postal_code', 'postal_code'), ('state', 'state'))
        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_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)