def process_pages(self, pages, dry_run): num_rates = 0 num_pages = 0 progress_bar = None try: for rates, total_pages in pages: if progress_bar is None: progress_bar = tqdm(total=total_pages) serializer = ContractSerializer(data=rates, many=True) if serializer.is_valid(): num_rates += len(rates) if not dry_run: serializer.save() else: rates_with_errors = [ (r, e) for r, e in zip(rates, serializer.errors) if e ] for rate, error in rates_with_errors: self.stderr.write( f"Rate {self.style.WARNING(rate)} has " f"error {self.style.ERROR(error)}!" ) progress_bar.update(1) num_pages += 1 finally: if progress_bar is not None: progress_bar.close() return num_rates, num_pages
def get(self, request): bins = request.query_params.get('histogram', None) wage_field = self.get_wage_field( request.query_params.get('contract-year')) contracts_all = self.get_queryset(request.query_params, wage_field) stats = contracts_all.aggregate(Min(wage_field), Max(wage_field), Avg(wage_field), StdDev(wage_field)) page_stats = { 'minimum': stats[wage_field + '__min'], 'maximum': stats[wage_field + '__max'], 'average': quantize(stats[wage_field + '__avg']), 'first_standard_deviation': quantize(stats[wage_field + '__stddev']) } if bins and bins.isnumeric(): values = contracts_all.values_list(wage_field, flat=True) page_stats['wage_histogram'] = get_histogram(values, int(bins)) pagination = self.pagination_class(page_stats) results = pagination.paginate_queryset(contracts_all, request) serializer = ContractSerializer(results, many=True) return pagination.get_paginated_response(serializer.data)
def test_end_date_update_invalid_if_shifts_exist_after( self, shifts_after_new_end_date_contract, contract_ending_in_february, end_date_before_months_with_shifts_contract_querydict, plain_request_object, ): """ Test if it is allowed to change the end_date to a earlier month even though there exist shifts afterwards to the new_end_date. :param shifts_after_new_end_date_contract: :param contract_ending_in_february: :param end_date_before_months_with_shifts_contract_querydict: :param plain_request_object: :return: """ with pytest.raises(serializers.ValidationError): ContractSerializer( instance=contract_ending_in_february, data=end_date_before_months_with_shifts_contract_querydict, context={ "request": plain_request_object }, ).is_valid(raise_exception=True)
def test_search_index_is_updated(self): rates = [{ 'idv_piid': 'GS-123-4567', 'vendor_name': 'Blarg Inc.', 'labor_category': 'Software Engineer', 'education_level': 'Bachelors', 'min_years_experience': 2, 'current_price': 100, 'hourly_rate_year1': 100 }] serializer = ContractSerializer(data=rates, many=True) if not serializer.is_valid(): raise AssertionError(serializer.errors) serializer.save() results = Contract.objects.all().multi_phrase_search('engineer').all() self.assertEqual([r.labor_category for r in results], ['Software Engineer'])
def test_search_index_is_updated(self): rates = [{ 'idv_piid': 'GS-123-4567', 'vendor_name': 'Blarg Inc.', 'labor_category': 'Software Engineer', 'education_level': 'Bachelors', 'min_years_experience': 2, 'current_price': 100, 'hourly_rate_year1': 100 }] serializer = ContractSerializer(data=rates, many=True) if not serializer.is_valid(): raise AssertionError(serializer.errors) serializer.save() results = Contract.objects.multi_phrase_search('engineer').all() self.assertEqual([r.labor_category for r in results], ['Software Engineer'])
def test_update_carryover_and_target_date_correct_evaluated( self, user_object, contract_ending_in_april, shift_contract_ending_in_april, plain_request_object, ): """ By the tests 'test_update_carryover_target_date_recreates_reports' and 'test_update_initial_carryover_minutes_updates_reports' we allready checked that PATCH'ing (parital updates) works. In order to not bother checking the Reports etc. for PUT'ing we just test the logic which determines whether or not either carryover_target_date and/or initial_carryover_minutes change (see update method of ContractSerializer). :param contract_ending_in_april: :param shift_contract_ending_in_april: :param plain_request_object: :return: """ data = { "name": "Test Contract1", "minutes": 1200, "start_date": datetime.date(2019, 1, 1), "end_date": datetime.date(2019, 4, 30), "user": str(user_object.id), "created_by": str(user_object.id), "modified_by": str(user_object.id), "created_at": contract_ending_in_april.created_at, "modified_at": contract_ending_in_april.modified_at, "carryover_target_date": datetime.date(2019, 2, 1), "initial_carryover_minutes": 600, } seri = ContractSerializer( instance=contract_ending_in_april, data=data, context={"request": plain_request_object}, ) seri.is_valid() validated_data = seri.validated_data carryover_target_date_changed = ( validated_data.get("carryover_target_date") != contract_ending_in_april.carryover_target_date) initial_carryover_minutes_changed = ( validated_data.get("initial_carryover_minutes") != contract_ending_in_april.initial_carryover_minutes) assert carryover_target_date_changed assert initial_carryover_minutes_changed
def get(self, request): user = request.user res = [] queryset = Contract.objects.filter(user=user) for contract in queryset: cur_contract = ContractSerializer(contract).data victims = contract.get_victim_list() for victim in victims: cur_contract[victim.username] = VictimSerializer(victim).data res.append(cur_contract) return JsonResponse(res, safe=False)
def test_validate_correct_data(self, valid_contract_querydict, plain_request_object): """ The ContractSerializer is tested if a valid JSON passes validation. :param valid_contract_querydict: :param plain_request_object: :return: """ ContractSerializer(data=valid_contract_querydict, context={ "request": plain_request_object }).is_valid(raise_exception=True)
def test_update_initial_carryover_minutes_updates_reports( self, contract_ending_in_april, shift_contract_ending_in_april, plain_request_object, ): """ Test wether the serializers update method also updates the Reports when we change the initial_carryover_minutes. :param contract_ending_in_april: :param shift_contract_ending_in_april: :return: """ assert Report.objects.get( contract=contract_ending_in_april, month_year=datetime.date( 2019, 3, 1)).worktime == datetime.timedelta(hours=10) seri = ContractSerializer( instance=contract_ending_in_april, data={"initial_carryover_minutes": 600}, partial=True, context={"request": plain_request_object}, ) seri.is_valid(raise_exception=True) seri.save() assert Report.objects.get( contract=contract_ending_in_april, month_year=datetime.date( 2019, 3, 1)).worktime == datetime.timedelta(hours=15)
def test_contract_ended_in_past_validation( self, plain_request_object, contract_ending_in_february_querydict): """ :param plain_request_object: :param contract_ending_in_february_json: :return: """ with pytest.raises(serializers.ValidationError): ContractSerializer( data=contract_ending_in_february_querydict, context={ "request": plain_request_object }, ).is_valid(raise_exception=True)
def test_update_contract_end_date( self, contract_end_date_7_months_apart_json, plain_request_object, contract_object, ): with pytest.raises(serializers.ValidationError): ContractSerializer( instance=contract_object, data=contract_end_date_7_months_apart_json, context={ "request": plain_request_object }, ).is_valid(raise_exception=True)
def construct_json_object(self, user): user_data = UserSerializer(user).data contract_data = ContractSerializer(Contract.objects.filter(user=user), many=True).data shift_data = ShiftSerializer(Shift.objects.filter(user=user), many=True).data report_data = ReportSerializer(Report.objects.filter(user=user), many=True).data return { "user_data": user_data, "contracts_data": contract_data, "shifts_data": shift_data, "reports_data": report_data, }
def test_negative_hours_validation(self, negative_hours_contract_querydict, plain_request_object): """ The ContractSerializer is tested whether it raises a Validation if the hours value is negative. :param negative_hours_contract_querydict: :param plain_request_object: :return: """ with pytest.raises(serializers.ValidationError) as e_info: ContractSerializer( data=negative_hours_contract_querydict, context={ "request": plain_request_object }, ).is_valid(raise_exception=True)
def get(self, request, format=None): contracts = self.get_queryset() if contracts == 1: return HttpResponseBadRequest( "You must provide a vendor DUNS to retrieve contracts.") elif not contracts: return Response({'num_results': 0, 'results': []}) else: serializer = ContractSerializer(contracts) return Response({ 'num_results': len(serializer.data), 'results': serializer.data })
def test_carryover_target_date_not_in_month_range( self, incorrect_carryover_target_date_contract_querydict, plain_request_object): """ Test if it is allowed to have a month_start_clocking not in-between start_date and end_date. :param incorrect_month_start_clocking_contract_querydict: :param plain_request_object: :return: """ with pytest.raises(serializers.ValidationError): ContractSerializer( data=incorrect_carryover_target_date_contract_querydict, context={ "request": plain_request_object }, ).is_valid(raise_exception=True)
def test_end_date_day_validation(self, end_date_day_incorrect_contract_querydict, plain_request_object): """ The ContractSerializer is tested whether it raises a Validation if the start_date day is not the 14. or last day of a month. :param end_date_day_incorrect_contract_querydict: :param plain_request_object: :return: """ with pytest.raises(serializers.ValidationError) as e_info: ContractSerializer( data=end_date_day_incorrect_contract_querydict, context={ "request": plain_request_object }, ).is_valid(raise_exception=True)
def test_start_date_causality_validation( self, end_date_before_start_date_contract_querydict, plain_request_object): """ The ContractSerializer is tested whether it raises a ValidationError if the start and end dates are causally correct. :param end_date_before_start_date_contract_querydict: :param plain_request_object: :return: """ with pytest.raises(serializers.ValidationError) as e_info: ContractSerializer( data=end_date_before_start_date_contract_querydict, context={ "request": plain_request_object }, ).is_valid(raise_exception=True)
def test_carryover_target_date_incorrect_date( self, incorrect_date_carryover_target_date_contract_querydict, plain_request_object, ): """ Test if it is allowed to have a month_start_clocking which is not the first of a month. :param incorrect_date_month_start_clocking_contract_querydict: :param plain_request_object: :return: """ with pytest.raises(serializers.ValidationError): ContractSerializer( data=incorrect_date_carryover_target_date_contract_querydict, context={ "request": plain_request_object }, ).is_valid(raise_exception=True)
def test_month_start_clocking_incorrect_for_future_contract( self, incorrect_carryover_target_date_for_future_contract_querydict, plain_request_object, ): """ Test if is allowed to set month_start_clock to a different date then start_date.replace(day=1) if contract starts in the future. :param incorrect_month_start_clocking_for_future_contract_querydict: :param plain_request_object: :return: """ with pytest.raises(serializers.ValidationError): ContractSerializer( data= incorrect_carryover_target_date_for_future_contract_querydict, context={ "request": plain_request_object }, ).is_valid(raise_exception=True)
def test_start_carry_over_non_zerofuture_contract( self, non_zero_initial_carryover_minutes_for_future_contract_querydict, plain_request_object, ): """ Test if is allowed to set start_carry_over to a non-zero timedelta for contracts starting in the future. :param non_zero_initial_carryover_minutes_for_future_contract_querydict: :param plain_request_object: :return: """ with pytest.raises(serializers.ValidationError): ContractSerializer( data= non_zero_initial_carryover_minutes_for_future_contract_querydict, context={ "request": plain_request_object }, ).is_valid(raise_exception=True)
def get(self, request): bins = request.query_params.get('histogram', None) """ wage_field determines prices for a given year: This year, next year, or the year after. Relies on indexing a list, which may be less reliable than a tuple. This is used both here in get() and downstream in get_query_set(), so we have to pass it through. """ possible_wage_fields = ['current_price', 'next_year_price', 'second_year_price'] year = request.query_params.get('contract-year', 0) wage_field = possible_wage_fields[int(year)] contracts_all = self.get_queryset(request.query_params, wage_field) stats = contracts_all.aggregate( Min(wage_field), Max(wage_field), Avg(wage_field), StdDev(wage_field)) page_stats = { 'minimum': stats[wage_field + '__min'], 'maximum': stats[wage_field + '__max'], 'average': quantize(stats[wage_field + '__avg']), 'first_standard_deviation': quantize( stats[wage_field + '__stddev'] ) } if bins and bins.isnumeric(): values = contracts_all.values_list(wage_field, flat=True) page_stats['wage_histogram'] = get_histogram(values, int(bins)) pagination = self.pagination_class(page_stats) results = pagination.paginate_queryset(contracts_all, request) serializer = ContractSerializer(results, many=True) return pagination.get_paginated_response(serializer.data)
def test_update_carryover_target_date_recreates_reports( self, contract_ending_in_april, shift_contract_ending_in_april, plain_request_object, ): """ Test wether the serializers update method deletes existing reports and recreates them when the carryover_target_date is updated. :param contract_ending_in_april: :param shift_contract_ending_in_april: :return: """ assert Report.objects.filter( contract=contract_ending_in_april).count() == 1 old_report_pk = Report.objects.filter( contract=contract_ending_in_april)[0].pk seri = ContractSerializer( instance=contract_ending_in_april, data={"carryover_target_date": datetime.date(2019, 2, 1)}, partial=True, context={"request": plain_request_object}, ) seri.is_valid(raise_exception=True) seri.save() assert Report.objects.filter( contract=contract_ending_in_april).count() == 2 assert not Report.objects.filter(pk=old_report_pk).exists() assert Report.objects.get( contract=contract_ending_in_april, month_year=datetime.date( 2019, 2, 1)).worktime == datetime.timedelta(hours=5) assert Report.objects.get( contract=contract_ending_in_april, month_year=datetime.date( 2019, 3, 1)).worktime == datetime.timedelta(hours=-10)