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)
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)
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 = 'mock_state' mock_property_view = mock.MagicMock() mock_request = mock.MagicMock() data = {'org_id': 1, 'cycle': 2, 'state': {'test': 3}, 'property': 4} serializer = PropertyViewAsStateSerializer() mock_request.METHOD = 'PUT' serializer.context = {'request': mock_request} serializer.update(mock_property_view, data) mock_serializer.assert_called_with(data={'test': 3}) self.assertTrue(mock_serializer.return_value.save.called)
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)
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() property = FakePropertyFactory(organization=self.org).get_property() data = { 'org_id': 1, 'cycle': 2, 'state': { 'test': 3 }, 'property': property.id } 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)
def update_with_building_sync(self, request, pk): """ Does not work in Swagger! Update an existing PropertyView with a building file. Currently only supports BuildingSync. --- consumes: - multipart/form-data parameters: - name: pk description: The PropertyView to update with this buildingsync file type: path required: true - name: organization_id type: integer required: true - name: cycle_id type: integer required: true - name: file_type type: string enum: ["Unknown", "BuildingSync"] required: true - name: file description: In-memory file object required: true type: file """ if len(request.FILES) == 0: return JsonResponse({ 'success': False, 'message': "Must pass file in as a Multipart/Form post" }) the_file = request.data['file'] file_type = BuildingFile.str_to_file_type( request.data.get('file_type', 'Unknown')) organization_id = request.query_params.get('organization_id', None) cycle_pk = request.query_params.get('cycle_id', None) if not cycle_pk: return JsonResponse({ 'success': False, 'message': "Cycle ID is not defined" }) else: cycle = Cycle.objects.get(pk=cycle_pk) result = self._get_property_view(pk, cycle_pk) p_status = False new_pv_state = None if result.get('status', None) != 'error': building_file = BuildingFile.objects.create( file=the_file, filename=the_file.name, file_type=file_type, ) property_view = result.pop('property_view') previous_state = property_view.state # passing in the existing propertyview allows it to process the buildingsync file and attach it to the # existing propertyview. p_status, new_pv_state, new_pv_view, messages = building_file.process( organization_id, cycle, property_view=property_view) # merge the relationships from the old property state self._merge_relationships(previous_state, new_pv_state) else: messages = [ 'Cannot match a PropertyView with property_id=%s; cycle_id=%s' % (pk, cycle_pk) ] if p_status and new_pv_state: return JsonResponse({ 'success': True, 'status': 'success', 'message': 'successfully imported file', 'data': { 'property_view': PropertyViewAsStateSerializer(new_pv_view).data, }, }) else: return JsonResponse( { 'status': 'error', 'message': "Could not process building file with messages {}".format( messages) }, status=status.HTTP_400_BAD_REQUEST)
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)
def create(self, request): """ Does not work in Swagger! Create a new Property from a building file. --- consumes: - multipart/form-data parameters: - name: organization_id type: integer required: true - name: cycle_id type: integer required: true - name: file_type type: string enum: ["Unknown", "BuildingSync", "HPXML"] required: true - name: file description: In-memory file object required: true type: file """ if len(request.FILES) == 0: return JsonResponse({ 'success': False, 'message': 'Must pass file in as a Multipart/Form post' }) the_file = request.data['file'] file_type = BuildingFile.str_to_file_type( request.data.get('file_type', 'Unknown')) organization_id = request.data['organization_id'] cycle = request.data.get('cycle_id', None) if not cycle: return JsonResponse({ 'success': False, 'message': 'Cycle ID is not defined' }) else: cycle = Cycle.objects.get(pk=cycle) # figure out if file is xml or zip the_filename = the_file._get_name() tmp_filename, file_extension = os.path.splitext(the_filename) # initialize p_status = True property_state = True messages = {'errors': [], 'warnings': []} if file_extension == '.zip': # ZIP FILE, extract and process files one by one # print("This file is a ZIP") with zipfile.ZipFile(the_file, "r", zipfile.ZIP_STORED) as openzip: filelist = openzip.infolist() for f in filelist: # print("FILE: {}".format(f.filename)) # process xml files if '.xml' in f.filename and '__MACOSX' not in f.filename: # print("PROCESSING file: {}".format(f.filename)) data_file = NamedTemporaryFile() data_file.write(openzip.read(f)) data_file.seek(0) size = os.path.getsize(data_file.name) content_type = 'text/xml' # print("DATAFILE:") # print(data_file) a_file = InMemoryUploadedFile(data_file, 'data_file', f.filename, content_type, size, charset=None) building_file = BuildingFile.objects.create( file=a_file, filename=f.filename, file_type=file_type, ) p_status_tmp, property_state_tmp, property_view, messages_tmp = building_file.process( organization_id, cycle) # print('messages_tmp: ') # print(messages_tmp) # append errors to overall messages for i in messages_tmp['errors']: messages['errors'].append(f.filename + ": " + i) for i in messages_tmp['warnings']: messages['warnings'].append(f.filename + ": " + i) if not p_status_tmp: # capture error p_status = p_status_tmp else: # capture a real property_state (not None) property_state = property_state_tmp else: # just an XML building_file = BuildingFile.objects.create( file=the_file, filename=the_file.name, file_type=file_type, ) p_status, property_state, property_view, messages = building_file.process( organization_id, cycle) if p_status and property_state: if len(messages['warnings']) > 0: return JsonResponse({ 'success': True, 'status': 'success', 'message': { 'warnings': messages['warnings'] }, 'data': { 'property_view': PropertyViewAsStateSerializer(property_view).data, # 'property_state': PropertyStateWritableSerializer(property_state).data, }, }) else: return JsonResponse({ 'success': True, 'status': 'success', 'message': { 'warnings': [] }, 'data': { 'property_view': PropertyViewAsStateSerializer(property_view).data, # 'property_state': PropertyStateWritableSerializer(property_state).data, }, }) else: return JsonResponse( { 'success': False, 'status': 'error', 'message': messages }, status=status.HTTP_400_BAD_REQUEST)
def create(self, request): """ Does not work in Swagger! Create a new Property from a building file. --- consumes: - multipart/form-data parameters: - name: organization_id type: integer required: true - name: cycle_id type: integer required: true - name: file_type type: string enum: ["Unknown", "BuildingSync", "GeoJSON", "HPXML"] required: true - name: file description: In-memory file object required: true type: file """ if len(request.FILES) == 0: return JsonResponse({ 'success': False, 'message': "Must pass file in as a Multipart/Form post" }) the_file = request.data['file'] file_type = BuildingFile.str_to_file_type(request.data.get('file_type', 'Unknown')) organization_id = request.data['organization_id'] cycle = request.data.get('cycle_id', None) if not cycle: return JsonResponse({ 'success': False, 'message': "Cycle ID is not defined" }) else: cycle = Cycle.objects.get(pk=cycle) building_file = BuildingFile.objects.create( file=the_file, filename=the_file.name, file_type=file_type, ) p_status, property_state, property_view, messages = building_file.process(organization_id, cycle) if p_status and property_state: return JsonResponse({ "status": "success", "message": "successfully imported file", "data": { "property_view": PropertyViewAsStateSerializer(property_view).data, # "property_state": PropertyStateWritableSerializer(property_state).data, }, }) else: return JsonResponse({ "status": "error", "message": "Could not process building file with messages {}".format(messages) }, status=status.HTTP_400_BAD_REQUEST)