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)
Example #2
0
 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)
Example #4
0
    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)
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
    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)