def test_apiview_check_permissions(rf): """Tests permission handlers which trigger a 403.""" class DisallowPermissionClass(object): def has_permission(self, request, view): return False def has_object_permission(self, request, view, obj): return True class AllowPermissionClass(object): def has_permission(self, request, view): return True def has_object_permission(self, request, view, obj): return True UserAPIView.permission_classes = [DisallowPermissionClass] view = UserAPIView.as_view() request = create_api_request(rf, url='/') response = view(request) response_data = json.loads(response.content) assert response.status_code == 403 assert 'msg' in response_data assert response_data['msg'] == 'Permission denied.' UserAPIView.permission_classes = [AllowPermissionClass] view = UserAPIView.as_view() request = create_api_request(rf, url='/') response = view(request) response_data = json.loads(response.content) assert response.status_code == 200
def test_toggle_quality_check(rf, admin): """Tests the view that mutes/unmutes quality checks.""" qc_filter = dict( false_positive=False, unit__state=TRANSLATED, unit__store__translation_project__project__disabled=False, ) qc = QualityCheck.objects.filter(**qc_filter).first() unit = qc.unit # Explicit POST data present, mute data = "mute=" request = create_api_request(rf, method="post", user=admin, data=data, encode_as_json=False) response = toggle_qualitycheck(request, unit.id, qc.id) assert response.status_code == 200 assert QualityCheck.objects.get(id=qc.id).false_positive is True # No POST data present, unmute request = create_api_request(rf, method="post", user=admin) response = toggle_qualitycheck(request, unit.id, qc.id) assert response.status_code == 200 assert QualityCheck.objects.get(id=qc.id).false_positive is False
def test_apiview_search(rf): """Tests filtering through a search query.""" # Note that `UserAPIView` is configured to search in all defined fields, # which are `username` and `full_name` view = UserAPIView.as_view() # Let's create some users to search for UserFactory.create(username='******', full_name='Foo Bar') UserFactory.create(username='******', full_name='Foo Bar') UserFactory.create(username='******', full_name='Foo Bar') # `q=bar` should match 3 users (full names match) request = create_api_request(rf, url='/?q=bar') response = view(request) response_data = json.loads(response.content) assert response.status_code == 200 assert len(response_data['models']) == 3 # `q=baz` should match 1 user request = create_api_request(rf, url='/?q=baz') response = view(request) response_data = json.loads(response.content) assert response.status_code == 200 assert len(response_data['models']) == 1 # Searches are case insensitive; `q=BaZ` should match 1 user request = create_api_request(rf, url='/?q=BaZ') response = view(request) response_data = json.loads(response.content) assert response.status_code == 200 assert len(response_data['models']) == 1
def test_apiview_check_object_permissions(rf): """Tests permission handlers which trigger a 403.""" class DisallowObjectPermissionClass(object): def has_permission(self, request, view): return True def has_object_permission(self, request, view, obj): return False class AllowObjectPermissionClass(object): def has_permission(self, request, view): return True def has_object_permission(self, request, view, obj): return True user = UserFactory.create(username='******') WriteableUserAPIView.permission_classes = [DisallowObjectPermissionClass] view = WriteableUserAPIView.as_view() request = create_api_request(rf, method='delete') response = view(request, id=user.id) response_data = json.loads(response.content) assert response.status_code == 403 assert 'msg' in response_data assert response_data['msg'] == 'Permission denied.' WriteableUserAPIView.permission_classes = [AllowObjectPermissionClass] view = WriteableUserAPIView.as_view() request = create_api_request(rf, method='delete') response = view(request, id=user.id) response_data = json.loads(response.content) assert response.status_code == 200
def test_apiview_put(rf): """Tests updating an object using the API.""" view = WriteableUserAPIView.as_view() user = UserFactory.create(username='******') # Malformed request, only JSON-encoded data is understood request = create_api_request(rf, 'put') response = view(request, id=user.id) response_data = json.loads(response.content) assert response.status_code == 400 assert response_data['msg'] == 'Invalid JSON data' # Update a field's data new_username = '******' update_data = { 'username': new_username, } request = create_api_request(rf, 'put', data=update_data) # Requesting unknown resources is a 404 response = view(request, id='11') assert response.status_code == 404 # All fields must be submitted response = view(request, id=user.id) response_data = json.loads(response.content) assert response.status_code == 400 assert 'errors' in response_data # Specify missing fields update_data.update({ 'email': user.email, }) request = create_api_request(rf, 'put', data=update_data) response = view(request, id=user.id) response_data = json.loads(response.content) # Now all is ok assert response.status_code == 200 assert response_data['username'] == new_username # Email shouldn't have changed assert response_data['email'] == user.email # View with a custom form update_data.update({ 'password': '******', }) view = WriteableUserSettingsAPIView.as_view() request = create_api_request(rf, 'put', data=update_data) response = view(request, id=user.id) response_data = json.loads(response.content) assert response.status_code == 200 assert 'password' not in response_data
def test_apiview_put(rf): """Tests updating an object using the API.""" view = WriteableUserAPIView.as_view() user = UserFactory.create(username="******") # Malformed request, only JSON-encoded data is understood request = create_api_request(rf, "put") response = view(request, id=user.id) response_data = json.loads(response.content) assert response.status_code == 400 assert response_data["msg"] == "Invalid JSON data" # Update a field's data new_username = "******" update_data = { "username": new_username, } request = create_api_request(rf, "put", data=update_data) # Requesting unknown resources is a 404 response = view(request, id="11") assert response.status_code == 404 # All fields must be submitted response = view(request, id=user.id) response_data = json.loads(response.content) assert response.status_code == 400 assert "errors" in response_data # Specify missing fields update_data.update({"email": user.email}) request = create_api_request(rf, "put", data=update_data) response = view(request, id=user.id) response_data = json.loads(response.content) # Now all is ok assert response.status_code == 200 assert response_data["username"] == new_username # Email shouldn't have changed assert response_data["email"] == user.email # View with a custom form update_data.update({"password": "******"}) view = WriteableUserSettingsAPIView.as_view() request = create_api_request(rf, "put", data=update_data) response = view(request, id=user.id) response_data = json.loads(response.content) assert response.status_code == 200 assert "password" not in response_data
def test_apiview_get_multiple(rf, no_extra_users): """Tests retrieving multiple objects using the API.""" view = UserAPIView.as_view() UserFactory.create(username='******') request = create_api_request(rf) response = view(request) response_data = json.loads(response.content) # Response should contain a 1-item list assert response.status_code == 200 assert isinstance(response_data, dict) assert 'count' in response_data assert 'models' in response_data assert len(response_data['models']) == User.objects.count() # Let's add more users UserFactory.create_batch(5) response = view(request) response_data = json.loads(response.content) assert response.status_code == 200 assert isinstance(response_data, dict) assert 'count' in response_data assert 'models' in response_data assert len(response_data['models']) == User.objects.count() # Let's add even more users to test pagination UserFactory.create_batch(5) response = view(request) response_data = json.loads(response.content) # First page is full assert response.status_code == 200 assert isinstance(response_data, dict) assert 'count' in response_data assert 'models' in response_data assert len(response_data['models']) == 10 request = create_api_request(rf, url='/?p=2') response = view(request) response_data = json.loads(response.content) # Second page constains a single user assert response.status_code == 200 assert isinstance(response_data, dict) assert 'count' in response_data assert 'models' in response_data assert len(response_data['models']) == User.objects.count() - 10
def test_get_uids(rf, default): """Tests units can be retrieved.""" view = get_uids # `path` query parameter missing request = create_api_request(rf, user=default) with pytest.raises(Http400): view(request) # `path` query parameter present request = create_api_request(rf, url="/?path=foo", user=default) with pytest.raises(Http404): view(request)
def test_get_uids_ordered(rf, default, admin, numbered_po): """Tests units can be retrieved while applying order filters.""" view = get_uids tp = numbered_po.translation_project url = ('/?path=/%s/%s/&filter=incomplete&sort=newest&initial=true' % (tp.language.code, tp.project.code)) request = create_api_request(rf, url=url, user=default) response = view(request) assert response.status_code == 200 request = create_api_request(rf, url=url, user=admin) response = view(request) assert response.status_code == 200
def test_apiview_invalid_method(rf): """Tests for invalid methods.""" view = UserAPIView.as_view() # Forbidden method request = create_api_request(rf, 'post') response = view(request) # "Method not allowed" if the method is not within the restricted list assert response.status_code == 405 # Non-existent method request = create_api_request(rf, 'patch') response = view(request) assert response.status_code == 405
def test_apiview_post(rf): """Tests creating a new object using the API.""" view = WriteableUserAPIView.as_view() # Malformed request, only JSON-encoded data is understood request = create_api_request(rf, "post") response = view(request) response_data = json.loads(response.content) assert response.status_code == 400 assert "msg" in response_data assert response_data["msg"] == "Invalid JSON data" # Not sending all required data fails validation missing_data = { "not_a_field": "not a value", } request = create_api_request(rf, "post", data=missing_data) response = view(request) response_data = json.loads(response.content) assert response.status_code == 400 assert "errors" in response_data # Sending all required data should create a new user data = { "username": "******", "email": "*****@*****.**", } request = create_api_request(rf, "post", data=data) response = view(request) response_data = json.loads(response.content) assert response.status_code == 200 assert response_data["username"] == "foo" user = User.objects.latest("id") assert user.username == "foo" # Trying to add the same user again should fail validation response = view(request) response_data = json.loads(response.content) assert response.status_code == 400 assert "errors" in response_data
def test_apiview_post(rf): """Tests creating a new object using the API.""" view = WriteableUserAPIView.as_view() # Malformed request, only JSON-encoded data is understood request = create_api_request(rf, 'post') response = view(request) response_data = json.loads(response.content) assert response.status_code == 400 assert 'msg' in response_data assert response_data['msg'] == 'Invalid JSON data' # Not sending all required data fails validation missing_data = { 'not_a_field': 'not a value', } request = create_api_request(rf, 'post', data=missing_data) response = view(request) response_data = json.loads(response.content) assert response.status_code == 400 assert 'errors' in response_data # Sending all required data should create a new user data = { 'username': '******', 'email': '*****@*****.**', } request = create_api_request(rf, 'post', data=data) response = view(request) response_data = json.loads(response.content) assert response.status_code == 200 assert response_data['username'] == 'foo' user = User.objects.latest('id') assert user.username == 'foo' # Trying to add the same user again should fail validation response = view(request) response_data = json.loads(response.content) assert response.status_code == 400 assert 'errors' in response_data
def test_apiview_put_multiple(rf): """Tests updating an object using the API.""" view = WriteableUserAPIView.as_view() request = create_api_request(rf, 'put') response = view(request) response_data = json.loads(response.content) assert response.status_code == 405 assert response_data['msg'] == 'PUT is not supported for collections'
def test_apiview_delete_meta_user(rf, meta_users): """Tests meta users cannot be removed.""" user = meta_users['user'] request = create_api_request(rf, 'delete') view = UserAPIView.as_view() response = view(request, id=user.id) assert response.status_code == 405 assert 'Cannot remove meta user instances' in response.content
def test_apiview_unhandled_exception(rf): """Tests exceptions can go unhandled.""" class UnhandledExceptionAPIView(UserAPIView): def get(self, request, *args, **kwargs): raise ValueError view = UnhandledExceptionAPIView.as_view() request = create_api_request(rf, url='/') with pytest.raises(ValueError): view(request)
def test_apiview_get_single(rf): """Tests retrieving a single object using the API.""" view = UserAPIView.as_view() user = UserFactory.create(username='******') request = create_api_request(rf) response = view(request, id=user.id) # This should have been a valid request... assert response.status_code == 200 # ...and JSON-encoded, so should properly parse it response_data = json.loads(response.content) assert isinstance(response_data, dict) assert response_data['username'] == 'foo' assert 'email' not in response_data # Non-existent IDs should return 404 response = view(request, id='777') assert response.status_code == 404
def test_apiview_delete(rf): """Tests deleting an object using the API.""" view = UserAPIView.as_view() user = UserFactory.create(username='******') # Delete is not supported for collections request = create_api_request(rf, 'delete') response = view(request) assert response.status_code == 405 assert User.objects.filter(id=user.id).count() == 1 # But it is supported for single items (specified by id): response = view(request, id=user.id) assert response.status_code == 200 assert User.objects.filter(id=user.id).count() == 0 # Should raise 404 if we try to access a deleted resource again: response = view(request, id=user.id) assert response.status_code == 404