graphql-engine/server/tests-py/test_v1alpha1_endpoint.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

155 lines
4.9 KiB
Python
Raw Normal View History

import pytest
from validate import check_query
import validate
from context import GQLWsClient
run default tests in test_server_upgrade (#3718) * run basic tests after upgrade * terminate before specifying file in pytest cmd * Move fixture definitions out of test classes Previously we had abstract classes with the fixtures defined in them. The test classes then inherits these super classes. This is creating inheritence problems, especially when you want to just inherit the tests in class, but not the fixtures. We have now moved all those fixture definitions outside of the class (in conftest.py). These fixtures are now used by the test classes when and where they are required. * Run pytests on server upgrade Server upgrade tests are run by 1) Run pytest with schema/metadata setup but do not do schema/metadata teardown 2) Upgrade the server 3) Run pytest using the above schema and teardown at the end of the tests 4) Cleanup hasura metadata and start again with next set of tests We have added options --skip-schema-setup and --skip-schema-teardown to help running server upgrade tests. While running the tests, we noticed that error codes and messages for some of the tests have changed. So we have added another option to pytest `--avoid-error-message-checks`. If this flag is set, and if comparing expected and response message fails, and if the expected response has an error message, Pytest will throw warnings instead of an error. * Use marks to specify server-upgrade tests Not all tests can be run as serve upgrade tests, particularly those which themselves change the schema. We introduce two pytest markers. Marker allow_server_upgrade_test will add the test into the list of server upgrade tests that can be run. skip_server_upgrade_test removes it from the list. With this we have added tests for queries, mutations, and selected event trigger and remote schema tests to the list of server upgrade tests. * Remove components not needed anymore * Install curl * Fix error in query validation * Fix error in test_v1_queries.py * install procps for server upgrade tests * Use postgres image which has postgis installed * set pager off with psql * quote the bash variable WORKTREE_DIR Co-authored-by: nizar-m <19857260+nizar-m@users.noreply.github.com> Co-authored-by: Vamshi Surabhi <0x777@users.noreply.github.com>
2020-02-13 12:14:02 +03:00
usefixtures = pytest.mark.usefixtures
run default tests in test_server_upgrade (#3718) * run basic tests after upgrade * terminate before specifying file in pytest cmd * Move fixture definitions out of test classes Previously we had abstract classes with the fixtures defined in them. The test classes then inherits these super classes. This is creating inheritence problems, especially when you want to just inherit the tests in class, but not the fixtures. We have now moved all those fixture definitions outside of the class (in conftest.py). These fixtures are now used by the test classes when and where they are required. * Run pytests on server upgrade Server upgrade tests are run by 1) Run pytest with schema/metadata setup but do not do schema/metadata teardown 2) Upgrade the server 3) Run pytest using the above schema and teardown at the end of the tests 4) Cleanup hasura metadata and start again with next set of tests We have added options --skip-schema-setup and --skip-schema-teardown to help running server upgrade tests. While running the tests, we noticed that error codes and messages for some of the tests have changed. So we have added another option to pytest `--avoid-error-message-checks`. If this flag is set, and if comparing expected and response message fails, and if the expected response has an error message, Pytest will throw warnings instead of an error. * Use marks to specify server-upgrade tests Not all tests can be run as serve upgrade tests, particularly those which themselves change the schema. We introduce two pytest markers. Marker allow_server_upgrade_test will add the test into the list of server upgrade tests that can be run. skip_server_upgrade_test removes it from the list. With this we have added tests for queries, mutations, and selected event trigger and remote schema tests to the list of server upgrade tests. * Remove components not needed anymore * Install curl * Fix error in query validation * Fix error in test_v1_queries.py * install procps for server upgrade tests * Use postgres image which has postgis installed * set pager off with psql * quote the bash variable WORKTREE_DIR Co-authored-by: nizar-m <19857260+nizar-m@users.noreply.github.com> Co-authored-by: Vamshi Surabhi <0x777@users.noreply.github.com>
2020-02-13 12:14:02 +03:00
@usefixtures('per_class_tests_db_state')
class TestV1Alpha1GraphQLErrors:
@classmethod
def dir(cls):
return 'queries/graphql_query/v1alpha1/errors'
def test_v1alpha1_authorization_error(self, hge_ctx):
gql_query = """
query {
author {
id
name
}
}
"""
http_conf = {
'url': '/v1alpha1/graphql',
'status': 200,
'query': {'query': gql_query},
}
if hge_ctx.hge_key is not None and hge_ctx.hge_webhook is None and hge_ctx.hge_jwt_key is None:
# Test whether it is forbidden when incorrect/no admin_secret is specified
validate.test_forbidden_when_admin_secret_reqd(hge_ctx, http_conf)
elif hge_ctx.hge_webhook is not None:
if not hge_ctx.webhook_insecure:
# Check whether the output is also forbidden when webhook returns forbidden
validate.test_forbidden_webhook(hge_ctx, http_conf)
else:
assert True
@pytest.mark.parametrize('transport', ['http', 'websocket'])
def test_v1alpha1_validation_error(self, hge_ctx, transport):
gql_query = """
query {
author {
id
name
notPresentCol
}
}
"""
http_conf = {
'url': '/v1alpha1/graphql',
'status': 400,
'query': {'query': gql_query},
'response': {
"errors": [{
"extensions": {
"path": "$.selectionSet.author.selectionSet.notPresentCol",
"code": "validation-failed"
},
An `ErrorMessage` type, to encapsulate. This introduces an `ErrorMessage` newtype which wraps `Text` in a manner which is designed to be easy to construct, and difficult to deconstruct. It provides functionality similar to `Data.Text.Extended`, but designed _only_ for error messages. Error messages are constructed through `fromString`, concatenation, or the `toErrorValue` function, which is designed to be overridden for all meaningful domain types that might show up in an error message. Notably, there are not and should never be instances of `ToErrorValue` for `String`, `Text`, `Int`, etc. This is so that we correctly represent the value in a way that is specific to its type. For example, all `Name` values (from the _graphql-parser-hs_ library) are single-quoted now; no exceptions. I have mostly had to add `instance ToErrorValue` for various backend types (and also add newtypes where necessary). Some of these are not strictly necessary for this changeset, as I had bigger aspirations when I started. These aspirations have been tempered by trying and failing twice. As such, in this changeset, I have started by introducing this type to the `parseError` and `parseErrorWith` functions. In the future, I would like to extend this to the `QErr` record and the various `throwError` functions, but this is a much larger task and should probably be done in stages. For now, `toErrorMessage` and `fromErrorMessage` are provided for conversion to and from `Text`, but the intent is to stop exporting these once all error messages are converted to the new type. PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5018 GitOrigin-RevId: 84b37e238992e4312255a87ca44f41af65e2d89a
2022-07-18 23:26:01 +03:00
"message": "field 'notPresentCol' not found in type: 'author'"
}]
}
}
ws_conf = {
'url': '/v1alpha1/graphql',
'query': {'query': gql_query},
'response': {
"path": "$.selectionSet.author.selectionSet.notPresentCol",
"code": "validation-failed",
An `ErrorMessage` type, to encapsulate. This introduces an `ErrorMessage` newtype which wraps `Text` in a manner which is designed to be easy to construct, and difficult to deconstruct. It provides functionality similar to `Data.Text.Extended`, but designed _only_ for error messages. Error messages are constructed through `fromString`, concatenation, or the `toErrorValue` function, which is designed to be overridden for all meaningful domain types that might show up in an error message. Notably, there are not and should never be instances of `ToErrorValue` for `String`, `Text`, `Int`, etc. This is so that we correctly represent the value in a way that is specific to its type. For example, all `Name` values (from the _graphql-parser-hs_ library) are single-quoted now; no exceptions. I have mostly had to add `instance ToErrorValue` for various backend types (and also add newtypes where necessary). Some of these are not strictly necessary for this changeset, as I had bigger aspirations when I started. These aspirations have been tempered by trying and failing twice. As such, in this changeset, I have started by introducing this type to the `parseError` and `parseErrorWith` functions. In the future, I would like to extend this to the `QErr` record and the various `throwError` functions, but this is a much larger task and should probably be done in stages. For now, `toErrorMessage` and `fromErrorMessage` are provided for conversion to and from `Text`, but the intent is to stop exporting these once all error messages are converted to the new type. PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5018 GitOrigin-RevId: 84b37e238992e4312255a87ca44f41af65e2d89a
2022-07-18 23:26:01 +03:00
"error": "field 'notPresentCol' not found in type: 'author'"
}
}
if transport == 'http':
check_query(hge_ctx, http_conf, transport)
elif transport == 'websocket':
check_query(hge_ctx, ws_conf, transport)
@pytest.mark.parametrize('transport', ['http', 'websocket'])
def test_v1alpha1_execution_error(self, hge_ctx, transport):
mutation = """
mutation {
insert_article (objects: [
{
title: "test 3"
content: "test 3 content"
author_id: 44
is_published: false
}
]) {
returning {
id
}
}
}
"""
http_conf = {
'url': '/v1alpha1/graphql',
'status': 400,
'query': {'query': mutation},
'response': {
"errors": [{
"extensions": {
"path": "$.selectionSet.insert_article.args.objects",
"code": "constraint-violation"
},
"message": "Foreign key violation. insert or update on table \"article\" violates foreign key constraint \"article_author_id_fkey\""
}]
}
}
ws_conf = {
'url': '/v1alpha1/graphql',
'query': {'query': mutation},
'response': {
'data': None,
"errors": [{
"path": "$.selectionSet.insert_article.args.objects",
"error": "Foreign key violation. insert or update on table \"article\" violates foreign key constraint \"article_author_id_fkey\"",
"code": "constraint-violation"
}]
}
}
if transport == 'http':
check_query(hge_ctx, http_conf, transport)
elif transport == 'websocket':
check_query(hge_ctx, ws_conf, transport)
def test_v1alpha1_ws_start_error(self, hge_ctx):
ws_client = GQLWsClient(hge_ctx, '/v1alpha1/graphql')
query = {'query': '{ author { name } }'}
frame = {
'id': '1',
'type': 'start',
'payload': query
}
ws_client.ws_active_query_ids.add('1')
ws_client.send(frame)
resp = ws_client.get_ws_query_event('1', 10)
print(resp)
assert 'type' in resp
assert resp['type'] == 'error'
assert 'payload' in resp
assert resp['payload'] == {
'path': '$',
'error': 'start received before the connection is initialised',
'code': 'start-failed'
}