Пример #1
0
def test_companies_list(user: User):
    """ Companies can be listed by a user.
    """

    client = APIClient()
    client.force_authenticate(user)

    do_test_company_listing(client)
Пример #2
0
def test_employments_list_public():
    """ Employees cannot be listed anonymously.
    """

    client = APIClient()

    resp = client.get(client.reverse('employment-list'))
    validate_jsonapi_error_response(resp, 403)
Пример #3
0
def test_create_company_public():
    """ Companies cannot be created by anonymous users.
    """

    client = APIClient()

    resp = client.post(client.reverse('company-list'),
                       data=COMPANIES_CREATE_REQUEST)
    validate_jsonapi_error_response(resp, expected_status_code=403)
Пример #4
0
def test_employments_details_public(other_employment: Employment):
    """ Employment details cannot be viewed anonymously.
    """

    client = APIClient()

    resp = client.get(
        client.reverse('employment-detail', pk=other_employment.pk))
    validate_jsonapi_error_response(resp, 403)
Пример #5
0
def do_test_company_listing(client: APIClient, batch_size=5):
    CompanyFactory.create_batch(batch_size)

    resp = client.get(client.reverse('company-list'))
    validate_jsonapi_list_response(
        resp,
        expected_count=batch_size,
        expected_attributes=ATTRIBUTES_LIST,
        expected_relationships=RELATIONSHIPS_LIST,
    )
Пример #6
0
def test_create_employment_public(company: Company):
    """ Employments cannot be created by anonymous users.
    """

    client = APIClient()

    req_data = get_employment_create_data_for(company, '*****@*****.**')

    resp = client.post(client.reverse('employment-list'), data=req_data)
    validate_jsonapi_error_response(resp, expected_status_code=403)
Пример #7
0
def test_companies_details_public(company: Company):
    """ Company details can also be viewed anonymously, only basic information is returned.
    """

    client = APIClient()

    resp = client.get(client.reverse('company-detail', pk=company.pk))
    validate_jsonapi_detail_response(
        resp,
        expected_attributes=ATTRIBUTES_PUBLIC,
        expected_relationships=RELATIONSHIPS_PUBLIC,
    )
Пример #8
0
def test_companies_create_only_fields(user: User):
    """ Ensures that create-only fields cannot be updated for existing instances.

    It also acts as general test for the create-only fields functionality.
    """

    client = APIClient()
    client.force_authenticate(user)

    # Part one - try creating a company without reg_code (required and create-only field) - this should fail
    req_data = deepcopy(COMPANIES_CREATE_REQUEST)
    del req_data['data']['attributes']['reg_code']
    resp = client.post(client.reverse('company-list'), data=req_data)
    validate_jsonapi_error_response(resp, expected_status_code=400)

    # Part two - create a company with all the necessary fields
    req_data = deepcopy(COMPANIES_CREATE_REQUEST)
    resp = client.post(client.reverse('company-list'), data=req_data)
    resp_data = validate_jsonapi_detail_response(resp,
                                                 expected_status_code=201)

    # Ensure everything is as intended
    req_data_attributes = req_data['data']['attributes']
    company = Company.objects.get(id=resp_data['data']['id'])
    for attr_name in req_data_attributes:
        assert getattr(company, attr_name) == req_data_attributes[attr_name]

    # Next, try updating the reg_code, which should be read-only
    new_reg_code = 123456
    assert company.reg_code != new_reg_code
    patch_data = {
        "data": {
            "type": "company",
            "id": str(company.id),
            "attributes": {
                'reg_code': new_reg_code,
            },
        },
    }

    # Try to update the value - it should be no-op
    resp = client.patch(client.reverse('company-detail', pk=company.pk),
                        patch_data)
    validate_jsonapi_detail_response(
        resp,
        expected_attributes=ATTRIBUTES_FULL,
        expected_relationships=RELATIONSHIPS_FULL,
    )
    # Ensure the value in database hasn't been changed
    refreshed_company = Company.objects.get(id=company.id)
    assert refreshed_company.reg_code == company.reg_code
Пример #9
0
def test_employments_update(employment: Employment, other_user: User):
    """ Admins should be able to update employment info (= role) of companies where they are admins.
    """

    assert employment.role == Employment.ROLE_ADMIN
    user = employment.user
    company = employment.company
    other_employment = Employment.objects.create(company=company,
                                                 user=other_user,
                                                 role=Employment.ROLE_NORMAL)

    client = APIClient()
    client.force_authenticate(user)

    patch_data = {
        "data": {
            "type": "employment",
            "id": str(other_employment.id),
            "attributes": {},
        },
    }

    # Part one - update the employment, changing role to admin
    updated = other_employment.updated
    patch_data['data']['attributes'] = {'role': Employment.ROLE_ADMIN}
    resp = client.patch(
        client.reverse('employment-detail', pk=other_employment.pk),
        patch_data)
    validate_jsonapi_detail_response(
        resp,
        expected_attributes=ATTRIBUTES_FULL,
        expected_relationships=RELATIONSHIPS_FULL,
    )
    refreshed_employment = Employment.objects.get(id=other_employment.id)
    assert refreshed_employment.role == Employment.ROLE_ADMIN
    assert refreshed_employment.updated > updated

    # Part two - PUT should not be allowed
    resp = client.put(
        client.reverse('employment-detail', pk=other_employment.pk),
        patch_data)
    validate_jsonapi_error_response(resp, expected_status_code=405)

    # Part three - updating is only allowed for admins, so it should fail after user is demoted to non-admin
    employment.role = Employment.ROLE_NORMAL
    employment.save()
    resp = client.patch(
        client.reverse('employment-detail', pk=other_employment.pk),
        patch_data)
    validate_jsonapi_error_response(resp, expected_status_code=403)
Пример #10
0
def test_employments_delete(employment: Employment, other_user: User,
                            other_employment: Employment):
    """ Ensures admins can delete employments but non-admin employees cannot.
    """

    assert employment.role == Employment.ROLE_ADMIN
    user = employment.user
    company = employment.company
    target_employment = Employment.objects.create(company=company,
                                                  user=other_user,
                                                  role=Employment.ROLE_NORMAL)

    client = APIClient()
    client.force_authenticate(user)

    # Part one - delete the company where the user is admin
    resp = client.delete(
        client.reverse('employment-detail', pk=target_employment.id))
    validate_response_status_code(resp, 204)
    assert not Employment.objects.filter(id=target_employment.id).exists()

    # Part two - try to delete an unrelated company - this should not be allowed
    resp = client.delete(
        client.reverse('employment-detail', pk=other_employment.id))
    validate_jsonapi_error_response(resp, expected_status_code=404)
    assert Employment.objects.filter(id=other_employment.id).exists()
Пример #11
0
def test_employments_list(employment: Employment, other_user: User,
                          other_company: Company):
    """ Employments can be listed by existing employees of a company.
    Users should see only employees of companies they themselves belong to.
    """

    user = employment.user

    client = APIClient()
    client.force_authenticate(user)

    Employment.objects.create(company=other_company,
                              user=other_user,
                              role=Employment.ROLE_ADMIN)
    assert Employment.objects.count() == 2

    # Ensure we only get a single employment back - the one belonging to the company we're in.
    resp = client.get(client.reverse('employment-list'))
    resp_data = validate_jsonapi_list_response(
        resp,
        expected_count=1,
        expected_attributes=ATTRIBUTES_LIST,
        expected_relationships=RELATIONSHIPS_LIST,
    )
    assert set(item['id']
               for item in resp_data['data']) == {str(employment.company_id)}
Пример #12
0
def test_employments_details_unrelated(user: User,
                                       other_employment: Employment):
    """ Employment details cannot be viewed by an unrelated user (non-employee).
    """

    client = APIClient()
    client.force_authenticate(user)

    resp = client.get(
        client.reverse('employment-detail', pk=other_employment.pk))
    validate_jsonapi_error_response(resp, 404)
Пример #13
0
def test_create_employment_unrelated(user: User, other_company: Company):
    """ Users who are not employees of a company cannot create employments for that company.
    """

    client = APIClient()
    client.force_authenticate(user)

    req_data = get_employment_create_data_for(other_company,
                                              '*****@*****.**')

    resp = client.post(client.reverse('employment-list'), data=req_data)
    validate_jsonapi_error_response(resp, expected_status_code=400)
Пример #14
0
def test_companies_details_unrelated(user: User, other_company: Company):
    """ Company details can be viewed by an unrelated user (non-employee), but only basic information is returned.
    """

    client = APIClient()
    client.force_authenticate(user)

    resp = client.get(client.reverse('company-detail', pk=other_company.pk))
    validate_jsonapi_detail_response(
        resp,
        expected_attributes=ATTRIBUTES_PUBLIC,
        expected_relationships=RELATIONSHIPS_PUBLIC,
    )
Пример #15
0
def test_companies_delete(employment: Employment, other_company: Company):
    """ Ensures admins can delete companies but non-admin employees cannot.
    """

    assert employment.role == Employment.ROLE_ADMIN
    user = employment.user
    company = employment.company

    client = APIClient()
    client.force_authenticate(user)

    # Part one - delete the company where the user is admin
    resp = client.delete(client.reverse('company-detail', pk=company.id))
    validate_response_status_code(resp, 204)
    assert not Company.objects.filter(id=company.id).exists()

    # Part two - try to delete an unrelated company - this should not be allowed
    resp = client.delete(client.reverse('company-detail', pk=other_company.id))
    validate_jsonapi_error_response(resp, expected_status_code=403)
    assert Company.objects.filter(id=other_company.id).exists()
Пример #16
0
def test_companies_details_employee(employment: Employment):
    """ Company details can be viewed by an employee, and full information is returned.
    """

    client = APIClient()
    client.force_authenticate(employment.user)

    resp = client.get(
        client.reverse('company-detail', pk=employment.company.pk))
    validate_jsonapi_detail_response(
        resp,
        expected_attributes=ATTRIBUTES_FULL,
        expected_relationships=RELATIONSHIPS_FULL,
    )
Пример #17
0
def test_create_company(user: User):
    """ Users should be able to create companies. They should become admin of the created company.
    """

    client = APIClient()
    client.force_authenticate(user)

    resp = client.post(client.reverse('company-list'),
                       data=COMPANIES_CREATE_REQUEST)
    data = validate_jsonapi_detail_response(resp, expected_status_code=201)

    assert Employment.objects.filter(user=user,
                                     company_id=data['data']['id'],
                                     role=Employment.ROLE_ADMIN).exists()
Пример #18
0
def test_create_employment_nonadmin(employment: Employment):
    """ Users who are not admin in a company cannot create employments for that company.
    """

    company = employment.company
    user = employment.user
    employment.role = Employment.ROLE_NORMAL
    employment.save()

    client = APIClient()
    client.force_authenticate(user)

    req_data = get_employment_create_data_for(company, '*****@*****.**')

    resp = client.post(client.reverse('employment-list'), data=req_data)
    validate_jsonapi_error_response(resp, expected_status_code=400)
Пример #19
0
def test_employments_details_employee(employment: Employment,
                                      other_user: User):
    """ Employment details can be viewed by an employee, and full information is returned.
    """

    company = employment.company
    other_employment = Employment.objects.create(company=company,
                                                 user=other_user,
                                                 role=Employment.ROLE_NORMAL)

    client = APIClient()
    client.force_authenticate(employment.user)

    resp = client.get(
        client.reverse('employment-detail', pk=other_employment.pk))
    validate_jsonapi_detail_response(
        resp,
        expected_attributes=ATTRIBUTES_FULL,
        expected_relationships=RELATIONSHIPS_FULL,
    )
Пример #20
0
def test_create_employment(employment: Employment):
    """ Admin users should be able to create employments in the same company.
    """

    company = employment.company
    user = employment.user
    assert employment.role == Employment.ROLE_ADMIN

    email = '*****@*****.**'
    assert not User.objects.filter(email=email).exists()

    client = APIClient()
    client.force_authenticate(user)

    req_data = get_employment_create_data_for(company, email)
    resp = client.post(client.reverse('employment-list'), data=req_data)
    validate_jsonapi_detail_response(resp, expected_status_code=201)

    assert User.objects.filter(email=email).exists()
    assert Employment.objects.filter(user=user,
                                     company=company,
                                     role=Employment.ROLE_ADMIN).exists()
Пример #21
0
def test_companies_list_public():
    """ Companies can also be listed anonymously.
    """

    client = APIClient()
    do_test_company_listing(client)
Пример #22
0
def test_companies_update(employment: Employment):
    assert employment.role == Employment.ROLE_ADMIN
    user = employment.user
    company = employment.company

    client = APIClient()
    client.force_authenticate(user)

    other_company = CompanyFactory.create()

    patch_data = {
        "data": {
            "type": "company",
            "id": str(company.id),
            "attributes": {},
        },
    }

    # Part one - update the company where the user is admin
    new_name = 'new name'
    updated = company.updated
    assert company.name != new_name
    patch_data['data']['attributes'] = {'name': new_name}
    resp = client.patch(client.reverse('company-detail', pk=company.pk),
                        patch_data)
    validate_jsonapi_detail_response(
        resp,
        expected_attributes=ATTRIBUTES_FULL,
        expected_relationships=RELATIONSHIPS_FULL,
    )
    refreshed_company = Company.objects.get(id=company.id)
    assert refreshed_company.name == new_name
    assert refreshed_company.updated > updated

    # Part two - PUT should not be allowed
    resp = client.put(client.reverse('company-detail', pk=company.pk),
                      patch_data)
    validate_jsonapi_error_response(resp, expected_status_code=405)

    # Part three - updating is only allowed for admins, so it should fail after user is demoted to non-admin
    employment.role = Employment.ROLE_NORMAL
    employment.save()
    resp = client.patch(client.reverse('company-detail', pk=company.pk),
                        patch_data)
    validate_jsonapi_error_response(resp, expected_status_code=403)

    # Part four - try to patch company where we don't have permissions
    patch_data['data']['id'] = str(other_company.id)
    resp = client.patch(client.reverse('company-detail', pk=other_company.pk))
    validate_jsonapi_error_response(resp, expected_status_code=403)