def test_notify_supervisors(db, mailoutbox):
    """Test time range 2017-7-17 till 2017-7-23."""
    start = date(2017, 7, 14)
    # supervisee with short time
    supervisee = UserFactory.create()
    supervisor = UserFactory.create()
    supervisee.supervisors.add(supervisor)

    EmploymentFactory.create(user=supervisee,
                             start_date=start,
                             percentage=100)
    workdays = rrule(DAILY, dtstart=start, until=date.today(),
                     # range is excluding last
                     byweekday=range(MO.weekday, FR.weekday + 1))
    for dt in workdays:
        ReportFactory.create(user=supervisee, date=dt,
                             duration=timedelta(hours=7))

    call_command('notify_supervisors_shorttime')

    # checks
    assert len(mailoutbox) == 1
    mail = mailoutbox[0]
    assert mail.to == [supervisor.email]
    body = mail.body
    assert 'Time range: 17.07.2017 - 23.07.2017\nRatio: 0.9' in body
    expected = (
        '{0} 35.0/42.5 (Ratio 0.82 Delta -7.5 Balance -9.0)'
    ).format(
        supervisee.get_full_name()
    )
    assert expected in body
def test_notify_reviewers(db, mailoutbox):
    """Test time range 2017-7-1 till 2017-7-31."""
    # a reviewer which will be notified
    reviewer_work = UserFactory.create()
    project_work = ProjectFactory.create()
    project_work.reviewers.add(reviewer_work)
    task_work = TaskFactory.create(project=project_work)
    ReportFactory.create(date=date(2017, 7, 1), task=task_work,
                         verified_by=None)

    # a reviewer which doesn't have any unverfied reports
    reviewer_no_work = UserFactory.create()
    project_no_work = ProjectFactory.create()
    project_no_work.reviewers.add(reviewer_no_work)
    task_no_work = TaskFactory.create(project=project_no_work)
    ReportFactory.create(date=date(2017, 7, 1), task=task_no_work,
                         verified_by=reviewer_no_work)

    call_command('notify_reviewers_unverified')

    # checks
    assert len(mailoutbox) == 1
    mail = mailoutbox[0]
    assert mail.to == [reviewer_work.email]
    url = (
        'http://localhost:4200/reschedule?from_date=2017-07-01&'
        'to_date=2017-07-31&reviewer=%d'
    ) % reviewer_work.id
    assert url in mail.body
def test_notify_reviewers_with_cc_and_message(db, mailoutbox, cc, message):
    """Test time range 2017-7-1 till 2017-7-31."""
    # a reviewer which will be notified
    reviewer_work = UserFactory.create()
    project_work = ProjectFactory.create()
    project_work.reviewers.add(reviewer_work)
    task_work = TaskFactory.create(project=project_work)
    ReportFactory.create(date=date(2017, 7, 1),
                         task=task_work,
                         verified_by=None)

    # a reviewer which doesn't have any unverfied reports
    reviewer_no_work = UserFactory.create()
    project_no_work = ProjectFactory.create()
    project_no_work.reviewers.add(reviewer_no_work)
    task_no_work = TaskFactory.create(project=project_no_work)
    ReportFactory.create(date=date(2017, 7, 1),
                         task=task_no_work,
                         verified_by=reviewer_no_work)

    call_command(
        "notify_reviewers_unverified",
        "--cc={0}".format(cc),
        "--message={0}".format(message),
    )

    # checks
    assert len(mailoutbox) == 1
    mail = mailoutbox[0]
    assert mail.to == [reviewer_work.email]
    url = ("http://localhost:4200/analysis?fromDate=2017-07-01&"
           "toDate=2017-07-31&reviewer=%d&editable=1") % reviewer_work.id
    assert url in mail.body
    assert message in mail.body
    assert mail.cc[0] == cc
def test_notify_supervisors_no_employment(db, mailoutbox):
    """Check that supervisees without employment do not notify supervisor."""
    supervisee = UserFactory.create()
    supervisor = UserFactory.create()
    supervisee.supervisors.add(supervisor)

    call_command('notify_supervisors_shorttime')

    assert len(mailoutbox) == 0
Пример #5
0
def test_worktime_balance_list_supervisor(auth_client):
    supervisee = UserFactory.create()
    UserFactory.create()
    auth_client.user.supervisees.add(supervisee)

    url = reverse("worktime-balance-list")

    result = auth_client.get(url, data={"date": "2017-01-01"})

    assert result.status_code == status.HTTP_200_OK

    json = result.json()
    assert len(json["data"]) == 2
Пример #6
0
def test_user_update_other(auth_client):
    """User may not change other user."""
    user = UserFactory.create()
    url = reverse('user-detail', args=[user.id])
    res = auth_client.patch(url)

    assert res.status_code == status.HTTP_403_FORBIDDEN
Пример #7
0
def test_report_list_filter_editable_reviewer(auth_client):
    user = auth_client.user
    # not editable report
    ReportFactory.create()

    # editable reports
    # 1st report of current user
    ReportFactory.create(user=user)
    # 2nd case: report of a project which has several
    # reviewers and report is created by current user
    report = ReportFactory.create(user=user)
    other_user = UserFactory.create()
    report.task.project.reviewers.add(user)
    report.task.project.reviewers.add(other_user)
    # 3rd case: report by other user and current user
    # is the reviewer
    reviewer_report = ReportFactory.create()
    reviewer_report.task.project.reviewers.add(user)

    url = reverse("report-list")

    response = auth_client.get(url, data={"editable": 1})
    assert response.status_code == status.HTTP_200_OK
    json = response.json()
    assert len(json["data"]) == 3
Пример #8
0
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'
Пример #9
0
def test_user_delete_superuser(superadmin_client):
    """Should not be able delete a user."""
    user = UserFactory.create()

    url = reverse('user-detail', args=[user.id])

    response = superadmin_client.delete(url)
    assert response.status_code == status.HTTP_204_NO_CONTENT
Пример #10
0
def test_user_worktime_list_superuser(auth_client):
    auth_client.user.is_superuser = True
    auth_client.user.save()
    supervisee = UserFactory.create()
    UserFactory.create()
    auth_client.user.supervisees.add(supervisee)

    url = reverse('worktime-balance-list')

    result = auth_client.get(url, data={
        'date': '2017-01-01',
    })

    assert result.status_code == status.HTTP_200_OK

    json = result.json()
    assert len(json['data']) == 3
Пример #11
0
def test_worktime_balance_list_filter_user(auth_client):
    supervisee = UserFactory.create()
    UserFactory.create()
    auth_client.user.supervisees.add(supervisee)

    url = reverse('worktime-balance-list')

    result = auth_client.get(url,
                             data={
                                 'date': '2017-01-01',
                                 'user': supervisee.id
                             })

    assert result.status_code == status.HTTP_200_OK

    json = result.json()
    assert len(json['data']) == 1
Пример #12
0
def test_user_delete_with_reports_superuser(superadmin_client):
    """Test that user with reports may not be deleted."""
    user = UserFactory.create()
    ReportFactory.create(user=user)

    url = reverse('user-detail', args=[user.id])

    response = superadmin_client.delete(url)
    assert response.status_code == status.HTTP_403_FORBIDDEN
Пример #13
0
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
Пример #14
0
def test_employment_unique_active(db):
    """Should only be able to have one active employment per user."""
    user = UserFactory.create()
    EmploymentFactory.create(user=user, end_date=None)
    employment = EmploymentFactory.create(user=user)
    form = EmploymentForm({"end_date": None}, instance=employment)

    with pytest.raises(ValueError):
        form.save()
Пример #15
0
def test_user_is_reviewer_filter(auth_client, value, expected):
    """Should filter users if they are a reviewer."""
    user = UserFactory.create()
    project = ProjectFactory.create()
    UserFactory.create_batch(3)

    project.reviewers.add(user)

    res = auth_client.get(reverse('user-list'), {'is_reviewer': value})
    assert len(res.json()['data']) == expected
def test_absence_balance_list_none_supervisee(auth_client):
    url = reverse("absence-balance-list")
    AbsenceTypeFactory.create()
    unrelated_user = UserFactory.create()

    result = auth_client.get(
        url, data={"user": unrelated_user.id, "date": "2017-01-03"}
    )
    assert result.status_code == status.HTTP_200_OK
    assert len(result.json()["data"]) == 0
Пример #17
0
def test_absence_balance_detail_none_supervisee(auth_client):
    url = reverse('absence-balance-list')
    absence_type = AbsenceTypeFactory.create()
    unrelated_user = UserFactory.create()

    url = reverse(
        'absence-balance-detail',
        args=['{0}_{1}_2017-03-01'.format(unrelated_user.id, absence_type.id)])

    result = auth_client.get(url)
    assert result.status_code == status.HTTP_404_NOT_FOUND
Пример #18
0
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
Пример #19
0
def test_absence_balance_list_none_supervisee(auth_client):
    url = reverse('absence-balance-list')
    AbsenceTypeFactory.create()
    unrelated_user = UserFactory.create()

    result = auth_client.get(url,
                             data={
                                 'user': unrelated_user.id,
                                 'date': '2017-01-03'
                             })
    assert result.status_code == status.HTTP_200_OK
    assert len(result.json()['data']) == 0
Пример #20
0
def test_user_attributes(auth_client, project):
    """Should filter users if they are a reviewer."""
    user = UserFactory.create()

    url = reverse("user-detail", args=[user.id])

    res = auth_client.get(url)
    assert not res.json()["data"]["attributes"]["is-reviewer"]

    project.reviewers.add(user)
    res = auth_client.get(url)
    assert res.json()["data"]["attributes"]["is-reviewer"]
Пример #21
0
def test_absence_credit_get_supervisor(auth_client):
    user = UserFactory.create()
    auth_client.user.supervisees.add(user)

    AbsenceCreditFactory.create_batch(1)
    AbsenceCreditFactory.create(user=auth_client.user)
    AbsenceCreditFactory.create(user=user)
    url = reverse("absence-credit-list")

    result = auth_client.get(url)
    assert result.status_code == status.HTTP_200_OK
    json = result.json()
    assert len(json["data"]) == 2
Пример #22
0
def test_overtime_credit_get_supervisor(auth_client):
    user = UserFactory.create()
    auth_client.user.supervisees.add(user)

    OvertimeCreditFactory.create_batch(1)
    OvertimeCreditFactory.create(user=auth_client.user)
    OvertimeCreditFactory.create(user=user)
    url = reverse('overtime-credit-list')

    result = auth_client.get(url)
    assert result.status_code == status.HTTP_200_OK
    json = result.json()
    assert len(json['data']) == 2
Пример #23
0
def test_employment_get_at(db):
    """Should return the right employment on a date."""
    user = UserFactory.create()
    employment = EmploymentFactory.create(user=user)

    assert Employment.objects.get_at(user, employment.start_date) == employment

    employment.end_date = employment.start_date + timedelta(days=20)

    employment.save()

    with pytest.raises(Employment.DoesNotExist):
        Employment.objects.get_at(user,
                                  employment.start_date + timedelta(days=21))
Пример #24
0
def test_employment_list_supervisor(auth_client):
    user = UserFactory.create()
    auth_client.user.supervisees.add(user)

    EmploymentFactory.create_batch(1)
    EmploymentFactory.create(user=auth_client.user)
    EmploymentFactory.create(user=user)

    url = reverse('employment-list')

    result = auth_client.get(url)
    assert result.status_code == status.HTTP_200_OK
    json = result.json()
    assert len(json['data']) == 2
def test_notify_reviewers(db, mailoutbox):
    """Test time range 2017-7-1 till 2017-7-31."""
    # a reviewer which will be notified
    reviewer_work = UserFactory.create()
    project_work = ProjectFactory.create()
    project_work.reviewers.add(reviewer_work)
    task_work = TaskFactory.create(project=project_work)
    ReportFactory.create(date=date(2017, 7, 1),
                         task=task_work,
                         verified_by=None)

    call_command("notify_reviewers_unverified")

    # checks
    assert len(mailoutbox) == 1
    mail = mailoutbox[0]
    assert mail.to == [reviewer_work.email]
    url = ("http://localhost:4200/analysis?fromDate=2017-07-01&"
           "toDate=2017-07-31&reviewer=%d&editable=1") % reviewer_work.id
    assert url in mail.body
Пример #26
0
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'
Пример #27
0
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_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"
Пример #29
0
def test_report_list_filter_editable_supervisor(auth_client):
    user = auth_client.user
    # not editable report
    ReportFactory.create()

    # editable reports
    # 1st case: report by current user
    ReportFactory.create(user=user)
    # 2nd case: report by current user with several supervisors
    report = ReportFactory.create(user=user)
    report.user.supervisors.add(user)
    other_user = UserFactory.create()
    report.user.supervisors.add(other_user)
    # 3rd case: report by different user with current user as supervisor
    supervisor_report = ReportFactory.create()
    supervisor_report.user.supervisors.add(user)

    url = reverse("report-list")

    response = auth_client.get(url, data={"editable": 1})
    assert response.status_code == status.HTTP_200_OK
    json = response.json()
    assert len(json["data"]) == 3
Пример #30
0
def test_report_verify_other_user(superadmin_client):
    """Verify that superuser may not verify to other user."""
    user = UserFactory.create()
    report = ReportFactory.create()

    data = {
        "data": {
            "type": "reports",
            "id": report.id,
            "relationships": {
                "verified-by": {
                    "data": {
                        "id": user.id,
                        "type": "users"
                    }
                }
            },
        }
    }

    url = reverse("report-detail", args=[report.id])
    response = superadmin_client.patch(url, data)
    assert response.status_code == status.HTTP_400_BAD_REQUEST