def test_user_transfer(superadmin_client): user = UserFactory.create() EmploymentFactory.create(user=user, start_date=date(2017, 12, 28), percentage=100) AbsenceTypeFactory.create(fill_worktime=True) AbsenceTypeFactory.create(fill_worktime=False) absence_type = AbsenceTypeFactory.create(fill_worktime=False) AbsenceFactory.create(user=user, type=absence_type, date=date(2017, 12, 29)) url = reverse('user-transfer', args=[user.id]) response = superadmin_client.post(url) assert response.status_code == status.HTTP_204_NO_CONTENT # running transfer twice should lead to same result response = superadmin_client.post(url) assert response.status_code == status.HTTP_204_NO_CONTENT assert user.overtime_credits.count() == 1 overtime_credit = user.overtime_credits.first() assert overtime_credit.transfer assert overtime_credit.date == date(2018, 1, 1) assert overtime_credit.duration == timedelta(hours=-8, minutes=-30) assert overtime_credit.comment == 'Transfer 2017' assert user.absence_credits.count() == 1 absence_credit = user.absence_credits.first() assert absence_credit.transfer assert absence_credit.date == date(2018, 1, 1) assert absence_credit.days == -1 assert absence_credit.comment == 'Transfer 2017'
def test_worktime_balance_with_employments(auth_client, django_assert_num_queries): # Calculate over one week start_date = date(2017, 3, 19) end_date = date(2017, 3, 26) employment = EmploymentFactory.create(user=auth_client.user, start_date=start_date, worktime_per_day=timedelta( hours=8, minutes=30), end_date=date(2017, 3, 23)) EmploymentFactory.create(user=auth_client.user, start_date=date(2017, 3, 24), worktime_per_day=timedelta(hours=8), end_date=None) # Overtime credit of 10 hours OvertimeCreditFactory.create(user=auth_client.user, date=start_date, duration=timedelta(hours=10, minutes=30)) # One public holiday during workdays PublicHolidayFactory.create(date=start_date, location=employment.location) # One public holiday on weekend PublicHolidayFactory.create(date=start_date + timedelta(days=1), location=employment.location) # 2x 10 hour reported worktime ReportFactory.create(user=auth_client.user, date=start_date + timedelta(days=3), duration=timedelta(hours=10)) ReportFactory.create(user=auth_client.user, date=start_date + timedelta(days=4), duration=timedelta(hours=10)) # one absence AbsenceFactory.create(user=auth_client.user, date=start_date + timedelta(days=5)) url = reverse('worktime-balance-detail', args=[ '{0}_{1}'.format(auth_client.user.id, end_date.strftime('%Y-%m-%d')) ]) with django_assert_num_queries(12): result = auth_client.get(url) assert result.status_code == status.HTTP_200_OK # 4 workdays 8.5 hours, 1 workday 8 hours, minus one holiday 8.5 # minutes 10.5 hours overtime credit expected_worktime = timedelta(hours=23) # 2 x 10 reports hours + 1 absence of 8 hours expected_reported = timedelta(hours=28) json = result.json() assert json['data']['attributes']['balance'] == ( duration_string(expected_reported - expected_worktime))
def test_absence_credit_balance(self): """Should calculate an absence credit balance.""" absence_credit = AbsenceCreditFactory.create( user=self.user, duration=timedelta(hours=30)) EmploymentFactory.create(user=self.user, start_date=absence_credit.date - timedelta(days=1), worktime_per_day=timedelta(hours=8)) AbsenceFactory.create(user=self.user, type=absence_credit.absence_type, date=absence_credit.date + timedelta(days=1)) AbsenceFactory.create(user=self.user, type=absence_credit.absence_type, date=absence_credit.date - timedelta(days=1), duration=timedelta(hours=8)) url = reverse('absence-credit-detail', args=[absence_credit.id]) res = self.client.get(url) result = self.result(res) assert result['data']['attributes']['duration'] == '1 06:00:00' assert result['data']['attributes']['used'] == '08:00:00' assert result['data']['attributes']['balance'] == '22:00:00'
def test_user_worktime_balance(self): """Should calculate correct worktime balances.""" user = self.user employment = user.employments.get(end_date__isnull=True) # Calculate over one week start_date = date(2017, 3, 19) end_date = date(2017, 3, 26) employment.start_date = start_date employment.worktime_per_day = timedelta(hours=8) employment.save() # Overtime credit of 10 hours OvertimeCreditFactory.create(user=user, date=start_date, duration=timedelta(hours=10, minutes=30)) # One public holiday during workdays PublicHolidayFactory.create(date=start_date, location=employment.location) # One public holiday on weekend PublicHolidayFactory.create(date=start_date + timedelta(days=1), location=employment.location) url = reverse('user-detail', args=[user.id]) res = self.client.get('{0}?until={1}'.format( url, end_date.strftime('%Y-%m-%d'))) result = self.result(res) # 5 workdays minus one holiday minus 10 hours overtime credit expected_worktime = (4 * employment.worktime_per_day - timedelta(hours=10, minutes=30)) assert (result['data']['attributes']['worktime-balance'] == duration_string(timedelta() - expected_worktime)) # 2x 10 hour reported worktime ReportFactory.create(user=user, date=start_date + timedelta(days=3), duration=timedelta(hours=10)) ReportFactory.create(user=user, date=start_date + timedelta(days=4), duration=timedelta(hours=10)) AbsenceFactory.create(user=user, date=start_date + timedelta(days=5)) res2 = self.client.get('{0}?until={1}'.format( url, end_date.strftime('%Y-%m-%d'))) result2 = self.result(res2) assert (result2['data']['attributes']['worktime-balance'] == duration_string(timedelta(hours=28) - expected_worktime))
def setUp(self): """Set the environment for the tests up.""" super().setUp() user = self.user other_user = User.objects.create_user(username='******', password='******') EmploymentFactory.create(user=user, start_date=datetime.date(2017, 5, 1), end_date=None) EmploymentFactory.create(user=other_user, start_date=datetime.date(2017, 5, 1), end_date=None) self.absences = [ AbsenceFactory.create(user=user, date=datetime.date(2017, 5, 1)), AbsenceFactory.create(user=user, date=datetime.date(2017, 5, 2)), AbsenceFactory.create(user=user, date=datetime.date(2017, 5, 3)) ] AbsenceFactory.create(user=other_user, date=datetime.date(2017, 5, 1)) AbsenceFactory.create(user=other_user, date=datetime.date(2017, 5, 2)) AbsenceFactory.create(user=other_user, date=datetime.date(2017, 5, 3))
def test_absence_list_supervisor(auth_client): user = UserFactory.create() auth_client.user.supervisees.add(user) AbsenceFactory.create(user=auth_client.user) AbsenceFactory.create(user=user) url = reverse("absence-list") response = auth_client.get(url) assert response.status_code == status.HTTP_200_OK json = response.json() assert len(json["data"]) == 2
def test_user_absence_types_fill_worktime(self): absence_type = AbsenceTypeFactory.create(fill_worktime=True) employment = self.user.employments.get(end_date__isnull=True) employment.worktime_per_day = timedelta(hours=5) employment.start_date = date.today() - timedelta(days=1) employment.save() ReportFactory.create( user=self.user, date=date.today(), duration=timedelta(hours=4) ) AbsenceFactory.create(date=date.today(), user=self.user, type=absence_type) AbsenceFactory.create(date=date.today() - timedelta(days=1), user=self.user, type=absence_type) url = reverse('user-detail', args=[ self.user.id ]) res = self.client.get(url, {'include': 'user_absence_types'}) assert res.status_code == HTTP_200_OK result = self.result(res) rel = result['data']['relationships'] inc = result['included'] assert len(rel['user-absence-types']['data']) == 1 assert len(inc) == 1 assert ( inc[0]['id'] == '{0}-{1}'.format(self.user.id, absence_type.id) ) assert inc[0]['attributes']['credit'] is None assert inc[0]['attributes']['balance'] is None assert inc[0]['attributes']['used-days'] is None assert inc[0]['attributes']['used-duration'] == '06:00:00'
def test_absence_delete_owner(auth_client): absence = AbsenceFactory.create(user=auth_client.user) url = reverse("absence-detail", args=[absence.id]) response = auth_client.delete(url) assert response.status_code == status.HTTP_204_NO_CONTENT
def test_absence_update_owner(auth_client): user = auth_client.user date = datetime.date(2017, 5, 3) absence = AbsenceFactory.create( user=auth_client.user, date=datetime.date(2016, 5, 3) ) EmploymentFactory.create( user=user, start_date=date, worktime_per_day=datetime.timedelta(hours=8) ) data = { "data": { "type": "absences", "id": absence.id, "attributes": {"date": date.strftime("%Y-%m-%d")}, } } url = reverse("absence-detail", args=[absence.id]) response = auth_client.patch(url, data) assert response.status_code == status.HTTP_200_OK json = response.json() assert json["data"]["attributes"]["date"] == "2017-05-03"
def test_absence_delete_superuser(superadmin_client): """Test that superuser may not delete absences of other users.""" user = UserFactory.create() absence = AbsenceFactory.create(user=user) url = reverse("absence-detail", args=[absence.id]) response = superadmin_client.delete(url) assert response.status_code == status.HTTP_403_FORBIDDEN
def test_absence_balance_full_day(auth_client, django_assert_num_queries): day = date(2017, 2, 28) user = auth_client.user EmploymentFactory.create(user=user, start_date=day) absence_type = AbsenceTypeFactory.create() AbsenceCreditFactory.create(date=day, user=user, days=5, absence_type=absence_type) # credit on different user, may not show up AbsenceCreditFactory.create(date=date.today(), absence_type=absence_type) AbsenceFactory.create(date=day, user=user, type=absence_type) AbsenceFactory.create(date=day - timedelta(days=1), user=user, type=absence_type) url = reverse('absence-balance-list') with django_assert_num_queries(7): result = auth_client.get(url, data={ 'date': '2017-03-01', 'user': user.id, 'include': 'absence_credits,absence_type' }) assert result.status_code == status.HTTP_200_OK json = result.json() assert len(json['data']) == 1 entry = json['data'][0] assert (entry['id'] == '{0}_{1}_2017-03-01'.format(user.id, absence_type.id)) assert entry['attributes']['credit'] == 5 assert entry['attributes']['used-days'] == 2 assert entry['attributes']['used-duration'] is None assert entry['attributes']['balance'] == 3 assert len(json['included']) == 2
def test_absence_detail(auth_client): absence = AbsenceFactory.create(user=auth_client.user) url = reverse("absence-detail", args=[absence.id]) response = auth_client.get(url) assert response.status_code == status.HTTP_200_OK json = response.json() assert json["data"]["id"] == str(absence.id)
def test_absence_list_authenticated(auth_client): absence = AbsenceFactory.create(user=auth_client.user) # overlapping absence with public holidays need to be hidden overlap_absence = AbsenceFactory.create( user=auth_client.user, date=datetime.date(2018, 1, 1) ) employment = EmploymentFactory.create( user=overlap_absence.user, start_date=datetime.date(2017, 12, 31) ) PublicHolidayFactory.create(date=overlap_absence.date, location=employment.location) url = reverse("absence-list") response = auth_client.get(url) assert response.status_code == status.HTTP_200_OK json = response.json() assert len(json["data"]) == 1 assert json["data"][0]["id"] == str(absence.id)
def test_absence_detail_unemployed(auth_client): """Test creation of absence fails on unemployed day.""" absence = AbsenceFactory.create(user=auth_client.user) url = reverse("absence-detail", args=[absence.id]) res = auth_client.get(url) assert res.status_code == status.HTTP_200_OK json = res.json() assert json["data"]["attributes"]["duration"] == "00:00:00"
def test_absence_balance_fill_worktime(auth_client, django_assert_num_queries): day = date(2017, 2, 28) user = UserFactory.create() user.supervisors.add(auth_client.user) EmploymentFactory.create(user=user, start_date=day, worktime_per_day=timedelta(hours=5)) absence_type = AbsenceTypeFactory.create(fill_worktime=True) ReportFactory.create(user=user, date=day + timedelta(days=1), duration=timedelta(hours=4)) AbsenceFactory.create(date=day + timedelta(days=1), user=user, type=absence_type) AbsenceFactory.create(date=day, user=user, type=absence_type) url = reverse('absence-balance-list') with django_assert_num_queries(12): result = auth_client.get(url, data={ 'date': '2017-03-01', 'user': user.id, 'include': 'absence_credits,absence_type' }) assert result.status_code == status.HTTP_200_OK json = result.json() assert len(json['data']) == 1 entry = json['data'][0] assert (entry['id'] == '{0}_{1}_2017-03-01'.format(user.id, absence_type.id)) assert entry['attributes']['credit'] is None assert entry['attributes']['balance'] is None assert entry['attributes']['used-days'] is None assert entry['attributes']['used-duration'] == '06:00:00'
def test_user_absence_types(self): absence_type = AbsenceTypeFactory.create() credit = AbsenceCreditFactory.create(date=date.today(), user=self.user, days=5, absence_type=absence_type) AbsenceFactory.create(date=date.today(), user=self.user, type=absence_type) AbsenceFactory.create(date=date.today() - timedelta(days=1), user=self.user, type=absence_type) url = reverse('user-detail', args=[ self.user.id ]) res = self.client.get(url, {'include': 'user_absence_types'}) assert res.status_code == HTTP_200_OK result = self.result(res) rel = result['data']['relationships'] inc = result['included'] assert len(rel['user-absence-types']['data']) == 1 assert len(inc) == 1 assert ( inc[0]['id'] == '{0}-{1}'.format(self.user.id, credit.absence_type.id) ) assert inc[0]['attributes']['credit'] == 5 assert inc[0]['attributes']['balance'] == 3 assert inc[0]['attributes']['used-days'] == 2 assert inc[0]['attributes']['used-duration'] is None
def test_absence_balance_fill_worktime(auth_client, django_assert_num_queries): day = date(2017, 2, 28) user = UserFactory.create() user.supervisors.add(auth_client.user) EmploymentFactory.create( user=user, start_date=day, worktime_per_day=timedelta(hours=5) ) absence_type = AbsenceTypeFactory.create(fill_worktime=True) ReportFactory.create( user=user, date=day + timedelta(days=1), duration=timedelta(hours=4) ) AbsenceFactory.create(date=day + timedelta(days=1), user=user, type=absence_type) AbsenceFactory.create(date=day, user=user, type=absence_type) url = reverse("absence-balance-list") with django_assert_num_queries(11): result = auth_client.get( url, data={ "date": "2017-03-01", "user": user.id, "include": "absence_credits,absence_type", }, ) assert result.status_code == status.HTTP_200_OK json = result.json() assert len(json["data"]) == 1 entry = json["data"][0] assert entry["id"] == "{0}_{1}_2017-03-01".format(user.id, absence_type.id) assert entry["attributes"]["credit"] is None assert entry["attributes"]["balance"] is None assert entry["attributes"]["used-days"] is None assert entry["attributes"]["used-duration"] == "06:00:00"
def test_absence_balance_full_day(auth_client, django_assert_num_queries): day = date(2017, 2, 28) user = auth_client.user EmploymentFactory.create(user=user, start_date=day) absence_type = AbsenceTypeFactory.create() AbsenceCreditFactory.create(date=day, user=user, days=5, absence_type=absence_type) # credit on different user, may not show up AbsenceCreditFactory.create(date=date.today(), absence_type=absence_type) AbsenceFactory.create(date=day, user=user, type=absence_type) AbsenceFactory.create(date=day - timedelta(days=1), user=user, type=absence_type) url = reverse("absence-balance-list") with django_assert_num_queries(6): result = auth_client.get( url, data={ "date": "2017-03-01", "user": user.id, "include": "absence_credits,absence_type", }, ) assert result.status_code == status.HTTP_200_OK json = result.json() assert len(json["data"]) == 1 entry = json["data"][0] assert entry["id"] == "{0}_{1}_2017-03-01".format(user.id, absence_type.id) assert entry["attributes"]["credit"] == 5 assert entry["attributes"]["used-days"] == 2 assert entry["attributes"]["used-duration"] is None assert entry["attributes"]["balance"] == 3 assert len(json["included"]) == 2
def test_absence_update_on_create_report(self): """Should update the absence after creating a new report.""" task = TaskFactory.create() type = AbsenceTypeFactory.create(fill_worktime=True) day = date(2017, 5, 3) employment = EmploymentFactory.create(user=self.user, start_date=day) absence = AbsenceFactory.create(user=self.user, date=day, type=type) Report.objects.create(user=self.user, date=day, task=task, duration=timedelta(hours=1)) assert (Absence.objects.get( pk=absence.pk).duration == employment.worktime_per_day - timedelta(hours=1))
def test_absence_update_superadmin_date(superadmin_client): """Test that superadmin may not change date of absence.""" user = UserFactory.create() date = datetime.date(2017, 5, 3) absence = AbsenceFactory.create(user=user, date=datetime.date(2016, 5, 3)) EmploymentFactory.create( user=user, start_date=date, worktime_per_day=datetime.timedelta(hours=8) ) data = { "data": { "type": "absences", "id": absence.id, "attributes": {"date": date.strftime("%Y-%m-%d")}, } } url = reverse("absence-detail", args=[absence.id]) response = superadmin_client.patch(url, data) assert response.status_code == status.HTTP_400_BAD_REQUEST
def test_absence_list_supervisee(auth_client): AbsenceFactory.create(user=auth_client.user) supervisors = UserFactory.create_batch(2) supervisors[0].supervisees.add(auth_client.user) AbsenceFactory.create(user=supervisors[0]) url = reverse("absence-list") response = auth_client.get(url) assert response.status_code == status.HTTP_200_OK json = response.json() assert len(json["data"]) == 1 # absences of multiple supervisors shouldn't affect supervisee supervisors[1].supervisees.add(auth_client.user) AbsenceFactory.create(user=supervisors[1]) response = auth_client.get(url) assert response.status_code == status.HTTP_200_OK json = response.json() assert len(json["data"]) == 1