diff --git a/community/boilerplates/auth-webhooks/python-flask/auth-webhook.py b/community/boilerplates/auth-webhooks/python-flask/auth-webhook.py index 803434d3b8907..d5f165a5ba5ef 100644 --- a/community/boilerplates/auth-webhooks/python-flask/auth-webhook.py +++ b/community/boilerplates/auth-webhooks/python-flask/auth-webhook.py @@ -1,5 +1,6 @@ from flask import Flask from flask import request, jsonify, abort + app = Flask(__name__) @@ -24,6 +25,7 @@ def get_details_for_token(token): def hello(): return 'webhook is running' + @app.route('/auth-webhook') def auth_webhook(): # get the auth token from Authorization header diff --git a/community/boilerplates/serverless-triggers/aws-lambda/python/echo/echo.py b/community/boilerplates/serverless-triggers/aws-lambda/python/echo/echo.py index 97eb1b5a35997..bb57a01f31d27 100644 --- a/community/boilerplates/serverless-triggers/aws-lambda/python/echo/echo.py +++ b/community/boilerplates/serverless-triggers/aws-lambda/python/echo/echo.py @@ -1,5 +1,6 @@ import json + def lambda_handler(event, context): try: body = json.loads(event['body']) diff --git a/community/boilerplates/serverless-triggers/aws-lambda/python/mutation/mutation.py b/community/boilerplates/serverless-triggers/aws-lambda/python/mutation/mutation.py index d5982b3879b1f..0cb0682b879b0 100644 --- a/community/boilerplates/serverless-triggers/aws-lambda/python/mutation/mutation.py +++ b/community/boilerplates/serverless-triggers/aws-lambda/python/mutation/mutation.py @@ -24,6 +24,7 @@ } """ + def lambda_handler(event, context): try: body = json.loads(event['body']) diff --git a/community/boilerplates/serverless-triggers/google-cloud-functions/python/echo/main.py b/community/boilerplates/serverless-triggers/google-cloud-functions/python/echo/main.py index 6f2bffb5ef757..e36070103890f 100644 --- a/community/boilerplates/serverless-triggers/google-cloud-functions/python/echo/main.py +++ b/community/boilerplates/serverless-triggers/google-cloud-functions/python/echo/main.py @@ -1,5 +1,6 @@ from flask import jsonify + def function(request): request_json = request.get_json() op = request_json['event']['op'] diff --git a/docs/_ext/lexer_jsx.py b/docs/_ext/lexer_jsx.py index b792a948c3e80..0c407d4a2eaa0 100644 --- a/docs/_ext/lexer_jsx.py +++ b/docs/_ext/lexer_jsx.py @@ -4,7 +4,6 @@ from pygments.lexers.javascript import JavascriptLexer from pygments.token import Name, Operator, Punctuation, String, Text - # Use same tokens as `JavascriptLexer`, but with tags and attributes support TOKENS = JavascriptLexer.tokens TOKENS.update({ @@ -26,7 +25,7 @@ ('{', Punctuation, 'expression'), ('".*?"', String, '#pop'), ("'.*?'", String, '#pop'), - default ('#pop') + default('#pop') ], 'expression': [ ('{', Punctuation, '#push'), diff --git a/docs/_ext/local_toctree.py b/docs/_ext/local_toctree.py index 4d9d147d1b085..353e536d0ada3 100644 --- a/docs/_ext/local_toctree.py +++ b/docs/_ext/local_toctree.py @@ -11,8 +11,8 @@ the maximum depth of the tree; set it to -1 to allow unlimited depth """ -def init_local_toctree(app): +def init_local_toctree(app): def _get_local_toctree(docname, **kwds): doctree = app.env.get_doctree(docname) if 'maxdepth' not in kwds: @@ -20,7 +20,7 @@ def _get_local_toctree(docname, **kwds): toctrees = [] for toctreenode in doctree.traverse(addnodes.toctree): toctree = app.env.resolve_toctree( - docname, app.builder, toctreenode, **kwds) + docname, app.builder, toctreenode, **kwds) toctrees.append(toctree) if not toctrees: return None diff --git a/docs/algolia_index/algolia_index.py b/docs/algolia_index/algolia_index.py index ca63be1ff9b09..fdb869a75eca6 100644 --- a/docs/algolia_index/algolia_index.py +++ b/docs/algolia_index/algolia_index.py @@ -32,6 +32,7 @@ def output_indexed_data(): print('\nTOTAL INDEXED: ' + str(count)) + def process_data(json_data): processed_data = [] @@ -44,7 +45,8 @@ def process_data(json_data): else: obj = json.loads(json.dumps(json_obj)) - split_content = [obj['content'][i:i + CONTENT_MAX_LENGTH] for i in range(0, len(obj['content']), CONTENT_MAX_LENGTH)] + split_content = [obj['content'][i:i + CONTENT_MAX_LENGTH] for i in + range(0, len(obj['content']), CONTENT_MAX_LENGTH)] for content_piece in split_content: obj = json.loads(json.dumps(json_obj)) diff --git a/docs/conf.py b/docs/conf.py index 4bee893a4139f..95d034bf67f9d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,11 +20,13 @@ import os import sys from os.path import abspath, dirname, join + sys.setrecursionlimit(2000) # Monkey patching StandaloneHTMLBuilder as to not include unnecessary scripts from sphinx.builders.html import StandaloneHTMLBuilder + # from sphinx.util.osutil import relative_uri StandaloneHTMLBuilder.script_files = ["_static/vendor.js"] # StandaloneHTMLBuilder.imgpath = relative_uri("v0.13", '_images') @@ -138,7 +140,7 @@ # The full version, including alpha/beta/rc tags. release = 'x.y' -#epilog rst lines for frequently reference links in docs +# epilog rst lines for frequently reference links in docs rst_epilog = """ """ @@ -185,7 +187,6 @@ # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' - # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] @@ -195,7 +196,6 @@ # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True - # -- Options for HTML output ---------------------------------------------- # import sphinx_rtd_theme # html_theme = "sphinx_rtd_theme" @@ -205,7 +205,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -#html_theme = 'alabaster' +# html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -325,21 +325,21 @@ # -- Options for LaTeX output --------------------------------------------- latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples diff --git a/server/tests-py/conftest.py b/server/tests-py/conftest.py index 1a583a2183a12..e6737adcd68f1 100644 --- a/server/tests-py/conftest.py +++ b/server/tests-py/conftest.py @@ -2,6 +2,7 @@ import time from context import HGECtx, HGECtxError + def pytest_addoption(parser): parser.addoption( "--hge-url", metavar="HGE_URL", help="url for graphql-engine", required=True @@ -23,9 +24,10 @@ def pytest_addoption(parser): "--hge-jwt-key-file", metavar="HGE_JWT_KEY_FILE", help="File containting the private key used to encode jwt tokens using RS512 algorithm", required=False ) + @pytest.fixture(scope='session') def hge_ctx(request): - print ("create hge_ctx") + print("create hge_ctx") hge_url = request.config.getoption('--hge-url') pg_url = request.config.getoption('--pg-url') hge_key = request.config.getoption('--hge-key') diff --git a/server/tests-py/context.py b/server/tests-py/context.py index 5397b80463c76..67162a46540e0 100644 --- a/server/tests-py/context.py +++ b/server/tests-py/context.py @@ -17,9 +17,11 @@ from sqlalchemy import create_engine from sqlalchemy.schema import MetaData + class HGECtxError(Exception): pass + class WebhookHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): self.send_response(HTTPStatus.OK) @@ -52,6 +54,7 @@ def server_bind(self): self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.bind(self.server_address) + class HGECtx: def __init__(self, hge_url, pg_url, hge_key, hge_webhook, hge_jwt_key_file, webhook_insecure): server_address = ('0.0.0.0', 5592) @@ -117,8 +120,7 @@ def get_ws_event(self, timeout): def reflect_tables(self): self.meta.reflect(bind=self.engine) - - def anyq(self, u, q, h): + def anyq(self, u, q, h): resp = self.http.post( self.hge_url + u, json=q, diff --git a/server/tests-py/test_events.py b/server/tests-py/test_events.py index 44e76ef6f012a..864e4284a07f0 100755 --- a/server/tests-py/test_events.py +++ b/server/tests-py/test_events.py @@ -6,6 +6,7 @@ import time from validate import check_event + def select_last_event_fromdb(hge_ctx): q = { "type": "select", @@ -19,7 +20,8 @@ def select_last_event_fromdb(hge_ctx): st_code, resp = hge_ctx.v1q(q) return st_code, resp -def insert(hge_ctx, table, row, returning = []): + +def insert(hge_ctx, table, row, returning=[]): q = { "type": "insert", "args": { @@ -31,6 +33,7 @@ def insert(hge_ctx, table, row, returning = []): st_code, resp = hge_ctx.v1q(q) return st_code, resp + def update(hge_ctx, table, where_exp, set_exp): q = { "type": "update", @@ -43,6 +46,7 @@ def update(hge_ctx, table, where_exp, set_exp): st_code, resp = hge_ctx.v1q(q) return st_code, resp + def delete(hge_ctx, table, where_exp): q = { "type": "delete", @@ -55,12 +59,11 @@ def delete(hge_ctx, table, where_exp): return st_code, resp - class TestCreateEvtQuery(object): @pytest.fixture(autouse=True) def transact(self, request, hge_ctx): - print ("In setup method") + print("In setup method") st_code, resp = hge_ctx.v1q_f('queries/event_triggers/basic/setup.yaml') assert st_code == 200, resp yield @@ -68,9 +71,9 @@ def transact(self, request, hge_ctx): assert st_code == 200, resp def test_basic(self, hge_ctx): - table = {"schema" : "hge_tests", "name": "test_t1"} + table = {"schema": "hge_tests", "name": "test_t1"} - init_row = {"c1" : 1, "c2" : "hello"} + init_row = {"c1": 1, "c2": "hello"} exp_ev_data = { "old": None, "new": init_row @@ -81,28 +84,29 @@ def test_basic(self, hge_ctx): check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data, headers, "/") where_exp = {"c1": 1} - set_exp = {"c2" : "world"} + set_exp = {"c2": "world"} exp_ev_data = { "old": init_row, - "new": {"c1" : 1, "c2" : "world"} + "new": {"c1": 1, "c2": "world"} } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp check_event(hge_ctx, "t1_all", table, "UPDATE", exp_ev_data, headers, "/") exp_ev_data = { - "old": {"c1" : 1, "c2" : "world"}, + "old": {"c1": 1, "c2": "world"}, "new": None } st_code, resp = delete(hge_ctx, table, where_exp) assert st_code == 200, resp check_event(hge_ctx, "t1_all", table, "DELETE", exp_ev_data, headers, "/") + class TestRetryConf(object): @pytest.fixture(autouse=True) def transact(self, request, hge_ctx): - print ("In setup method") + print("In setup method") st_code, resp = hge_ctx.v1q_f('queries/event_triggers/retry_conf/setup.yaml') assert st_code == 200, resp yield @@ -110,9 +114,9 @@ def transact(self, request, hge_ctx): assert st_code == 200, resp def test_basic(self, hge_ctx): - table = {"schema" : "hge_tests", "name": "test_t1"} + table = {"schema": "hge_tests", "name": "test_t1"} - init_row = {"c1" : 1, "c2" : "hello"} + init_row = {"c1": 1, "c2": "hello"} exp_ev_data = { "old": None, "new": init_row @@ -124,11 +128,12 @@ def test_basic(self, hge_ctx): tries = hge_ctx.get_error_queue_size() assert tries == 5, tries + class TestEvtHeaders(object): @pytest.fixture(autouse=True) def transact(self, request, hge_ctx): - print ("In setup method") + print("In setup method") st_code, resp = hge_ctx.v1q_f('queries/event_triggers/headers/setup.yaml') assert st_code == 200, resp yield @@ -136,9 +141,9 @@ def transact(self, request, hge_ctx): assert st_code == 200, resp def test_basic(self, hge_ctx): - table = {"schema" : "hge_tests", "name": "test_t1"} + table = {"schema": "hge_tests", "name": "test_t1"} - init_row = {"c1" : 1, "c2" : "hello"} + init_row = {"c1": 1, "c2": "hello"} exp_ev_data = { "old": None, "new": init_row @@ -148,11 +153,12 @@ def test_basic(self, hge_ctx): assert st_code == 200, resp check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data, headers, "/") + class TestUpdateEvtQuery(object): @pytest.fixture(autouse=True) def transact(self, request, hge_ctx): - print ("In setup method") + print("In setup method") st_code, resp = hge_ctx.v1q_f('queries/event_triggers/update_query/create-setup.yaml') assert st_code == 200, resp st_code, resp = hge_ctx.v1q_f('queries/event_triggers/update_query/update-setup.yaml') @@ -162,10 +168,9 @@ def transact(self, request, hge_ctx): assert st_code == 200, resp def test_update_basic(self, hge_ctx): + table = {"schema": "hge_tests", "name": "test_t1"} - table = {"schema" : "hge_tests", "name": "test_t1"} - - init_row = {"c1" : 1, "c2" : "hello"} + init_row = {"c1": 1, "c2": "hello"} exp_ev_data = { "old": None, "new": {"c1": 1, "c2": "hello"} @@ -176,7 +181,7 @@ def test_update_basic(self, hge_ctx): check_event(hge_ctx, "t1_cols", table, "INSERT", exp_ev_data, headers, "/new") where_exp = {"c1": 1} - set_exp = {"c2" : "world"} + set_exp = {"c2": "world"} # expected no event hence previous expected data st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp @@ -184,10 +189,10 @@ def test_update_basic(self, hge_ctx): check_event(hge_ctx, "t1_cols", table, "UPDATE", exp_ev_data, headers, "/new") where_exp = {"c1": 1} - set_exp = {"c1" : 2} + set_exp = {"c1": 2} exp_ev_data = { - "old": {"c1" : 1, "c2": "world"}, - "new": {"c1" : 2, "c2": "world"} + "old": {"c1": 1, "c2": "world"}, + "new": {"c1": 2, "c2": "world"} } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp @@ -195,18 +200,19 @@ def test_update_basic(self, hge_ctx): where_exp = {"c1": 2} exp_ev_data = { - "old": {"c1" : 2, "c2" : "world"}, + "old": {"c1": 2, "c2": "world"}, "new": None } st_code, resp = delete(hge_ctx, table, where_exp) assert st_code == 200, resp check_event(hge_ctx, "t1_cols", table, "DELETE", exp_ev_data, headers, "/new") + class TestDeleteEvtQuery(object): @pytest.fixture(autouse=True) def transact(self, request, hge_ctx): - print ("In setup method") + print("In setup method") st_code, resp = hge_ctx.v1q_f('queries/event_triggers/basic/setup.yaml') assert st_code == 200, resp st_code, resp = hge_ctx.v1q_f('queries/event_triggers/delete_query/setup.yaml') @@ -216,9 +222,9 @@ def transact(self, request, hge_ctx): assert st_code == 200, resp def test_delete_basic(self, hge_ctx): - table = {"schema" : "hge_tests", "name": "test_t1"} + table = {"schema": "hge_tests", "name": "test_t1"} - init_row = {"c1" : 1, "c2" : "hello"} + init_row = {"c1": 1, "c2": "hello"} exp_ev_data = { "old": None, "new": init_row @@ -230,10 +236,10 @@ def test_delete_basic(self, hge_ctx): check_event(hge_ctx, "t1_all", table, "INSERT", exp_ev_data, headers, "/") where_exp = {"c1": 1} - set_exp = {"c2" : "world"} + set_exp = {"c2": "world"} exp_ev_data = { "old": init_row, - "new": {"c1" : 1, "c2" : "world"} + "new": {"c1": 1, "c2": "world"} } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp @@ -241,7 +247,7 @@ def test_delete_basic(self, hge_ctx): check_event(hge_ctx, "t1_all", table, "UPDATE", exp_ev_data, headers, "/") exp_ev_data = { - "old": {"c1" : 1, "c2" : "world"}, + "old": {"c1": 1, "c2": "world"}, "new": None } st_code, resp = delete(hge_ctx, table, where_exp) @@ -254,7 +260,7 @@ class TestEvtSelCols: @pytest.fixture(autouse=True) def transact(self, request, hge_ctx): - print ("In setup method") + print("In setup method") st_code, resp = hge_ctx.v1q_f('queries/event_triggers/selected_cols/setup.yaml') assert st_code == 200, resp yield @@ -262,10 +268,9 @@ def transact(self, request, hge_ctx): assert st_code == 200, resp def test_selected_cols(self, hge_ctx): + table = {"schema": "hge_tests", "name": "test_t1"} - table = {"schema" : "hge_tests", "name": "test_t1"} - - init_row = {"c1" : 1, "c2" : "hello"} + init_row = {"c1": 1, "c2": "hello"} exp_ev_data = { "old": None, "new": {"c1": 1, "c2": "hello"} @@ -276,7 +281,7 @@ def test_selected_cols(self, hge_ctx): check_event(hge_ctx, "t1_cols", table, "INSERT", exp_ev_data, headers, "/") where_exp = {"c1": 1} - set_exp = {"c2" : "world"} + set_exp = {"c2": "world"} # expected no event hence previous expected data st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp @@ -284,10 +289,10 @@ def test_selected_cols(self, hge_ctx): check_event(hge_ctx, "t1_cols", table, "UPDATE", exp_ev_data, headers, "/") where_exp = {"c1": 1} - set_exp = {"c1" : 2} + set_exp = {"c1": 2} exp_ev_data = { - "old": {"c1" : 1, "c2": "world"}, - "new": {"c1" : 2, "c2": "world"} + "old": {"c1": 1, "c2": "world"}, + "new": {"c1": 2, "c2": "world"} } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp @@ -295,16 +300,14 @@ def test_selected_cols(self, hge_ctx): where_exp = {"c1": 2} exp_ev_data = { - "old": {"c1" : 2, "c2" : "world"}, + "old": {"c1": 2, "c2": "world"}, "new": None } st_code, resp = delete(hge_ctx, table, where_exp) assert st_code == 200, resp check_event(hge_ctx, "t1_cols", table, "DELETE", exp_ev_data, headers, "/") - def test_selected_cols_dep(self, hge_ctx): - st_code, resp = hge_ctx.v1q({ "type": "run_sql", "args": { @@ -322,23 +325,22 @@ def test_selected_cols_dep(self, hge_ctx): }) assert st_code == 200, resp + class TestEvtInsertOnly: @pytest.fixture(autouse=True) def transact(self, request, hge_ctx): - print ("In setup method") + print("In setup method") st_code, resp = hge_ctx.v1q_f('queries/event_triggers/insert_only/setup.yaml') assert st_code == 200, resp yield st_code, resp = hge_ctx.v1q_f('queries/event_triggers/insert_only/teardown.yaml') assert st_code == 200, resp - def test_insert_only(self, hge_ctx): + table = {"schema": "hge_tests", "name": "test_t1"} - table = {"schema" : "hge_tests", "name": "test_t1"} - - init_row = {"c1" : 1, "c2" : "hello"} + init_row = {"c1": 1, "c2": "hello"} exp_ev_data = { "old": None, "new": init_row @@ -349,10 +351,10 @@ def test_insert_only(self, hge_ctx): check_event(hge_ctx, "t1_insert", table, "INSERT", exp_ev_data, headers, "/") where_exp = {"c1": 1} - set_exp = {"c2" : "world"} + set_exp = {"c2": "world"} exp_ev_data = { "old": init_row, - "new": {"c1" : 1, "c2" : "world"} + "new": {"c1": 1, "c2": "world"} } st_code, resp = update(hge_ctx, table, where_exp, set_exp) assert st_code == 200, resp @@ -360,7 +362,7 @@ def test_insert_only(self, hge_ctx): check_event(hge_ctx, "t1_insert", table, "UPDATE", exp_ev_data, headers, "/") exp_ev_data = { - "old": {"c1" : 1, "c2" : "world"}, + "old": {"c1": 1, "c2": "world"}, "new": None } st_code, resp = delete(hge_ctx, table, where_exp) @@ -368,11 +370,12 @@ def test_insert_only(self, hge_ctx): with pytest.raises(queue.Empty): check_event(hge_ctx, "t1_insert", table, "DELETE", exp_ev_data, headers, "/") + class TestEvtSelPayload: @pytest.fixture(autouse=True) def transact(self, request, hge_ctx): - print ("In setup method") + print("In setup method") st_code, resp = hge_ctx.v1q_f('queries/event_triggers/selected_payload/setup.yaml') assert st_code == 200, resp yield @@ -380,10 +383,9 @@ def transact(self, request, hge_ctx): assert st_code == 200, resp def test_selected_payload(self, hge_ctx): + table = {"schema": "hge_tests", "name": "test_t1"} - table = {"schema" : "hge_tests", "name": "test_t1"} - - init_row = {"c1" : 1, "c2" : "hello"} + init_row = {"c1": 1, "c2": "hello"} exp_ev_data = { "old": None, "new": {"c1": 1, "c2": "hello"} @@ -394,7 +396,7 @@ def test_selected_payload(self, hge_ctx): check_event(hge_ctx, "t1_payload", table, "INSERT", exp_ev_data, headers, "/") where_exp = {"c1": 1} - set_exp = {"c2" : "world"} + set_exp = {"c2": "world"} exp_ev_data = { "old": {"c1": 1}, "new": {"c1": 1} @@ -404,7 +406,7 @@ def test_selected_payload(self, hge_ctx): check_event(hge_ctx, "t1_payload", table, "UPDATE", exp_ev_data, headers, "/") where_exp = {"c1": 1} - set_exp = {"c1" : 2} + set_exp = {"c1": 2} exp_ev_data = { "old": {"c1": 1}, "new": {"c1": 2} @@ -415,7 +417,7 @@ def test_selected_payload(self, hge_ctx): where_exp = {"c1": 2} exp_ev_data = { - "old": {"c2" : "world"}, + "old": {"c2": "world"}, "new": None } st_code, resp = delete(hge_ctx, table, where_exp) @@ -423,7 +425,6 @@ def test_selected_payload(self, hge_ctx): check_event(hge_ctx, "t1_payload", table, "DELETE", exp_ev_data, headers, "/") def test_selected_payload_dep(self, hge_ctx): - st_code, resp = hge_ctx.v1q({ "type": "run_sql", "args": { diff --git a/server/tests-py/test_graphql_introspection.py b/server/tests-py/test_graphql_introspection.py index 009a7c51c77dc..f00a3ff461e2d 100644 --- a/server/tests-py/test_graphql_introspection.py +++ b/server/tests-py/test_graphql_introspection.py @@ -2,6 +2,7 @@ from validate import check_query_f, check_query from super_classes import DefaultTestSelectQueries + class TestGraphqlIntrospection(DefaultTestSelectQueries): def test_introspection(self, hge_ctx): diff --git a/server/tests-py/test_graphql_mutations.py b/server/tests-py/test_graphql_mutations.py index c0a6332167210..886ef7172ed87 100644 --- a/server/tests-py/test_graphql_mutations.py +++ b/server/tests-py/test_graphql_mutations.py @@ -39,10 +39,10 @@ def dir(cls): class TestGraphqlInsertOnConflict(DefaultTestQueries): def test_on_conflict_update(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/article_on_conflict_update.yaml") + check_query_f(hge_ctx, self.dir() + "/article_on_conflict_update.yaml") def test_on_conflict_no_action_specified(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/article_on_conflict_no_action_specified.yaml") + check_query_f(hge_ctx, self.dir() + "/article_on_conflict_no_action_specified.yaml") def test_on_conflict_ignore(self, hge_ctx): check_query_f(hge_ctx, self.dir() + "/article_on_conflict_ignore_constraint.yaml") @@ -53,13 +53,13 @@ def test_on_conflict_update_empty_cols(self, hge_ctx): hge_ctx.may_skip_test_teardown = True def test_err_missing_article_constraint(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/article_on_conflict_error_missing_article_constraint.yaml") + check_query_f(hge_ctx, self.dir() + "/article_on_conflict_error_missing_article_constraint.yaml") def test_err_unexpected_action(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/article_unexpected_on_conflict_action.yaml") + check_query_f(hge_ctx, self.dir() + "/article_unexpected_on_conflict_action.yaml") def test_err_unexpected_constraint(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/article_unexpected_on_conflict_constraint_error.yaml") + check_query_f(hge_ctx, self.dir() + "/article_unexpected_on_conflict_constraint_error.yaml") @classmethod def dir(cls): @@ -88,31 +88,31 @@ def test_user_err_unexpected_action(self, hge_ctx): check_query_f(hge_ctx, self.dir() + "/user_article_error_unexpected_on_conflict_action.yaml") def test_user_err_unexpected_constraint(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/user_article_unexpected_on_conflict_constraint_error.yaml") + check_query_f(hge_ctx, self.dir() + "/user_article_unexpected_on_conflict_constraint_error.yaml") def test_role_has_no_permissions_err(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/address_permission_error.yaml") + check_query_f(hge_ctx, self.dir() + "/address_permission_error.yaml") def test_author_user_role_insert_check_perm_success(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/author_user_role_insert_check_perm_success.yaml") + check_query_f(hge_ctx, self.dir() + "/author_user_role_insert_check_perm_success.yaml") def test_user_role_insert_check_is_registered_fail(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/author_user_role_insert_check_is_registered_fail.yaml") + check_query_f(hge_ctx, self.dir() + "/author_user_role_insert_check_is_registered_fail.yaml") def test_user_role_insert_check_user_id_fail(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/author_user_role_insert_check_user_id_fail.yaml") + check_query_f(hge_ctx, self.dir() + "/author_user_role_insert_check_user_id_fail.yaml") def test_student_role_insert_check_bio_success(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/author_student_role_insert_check_bio_success.yaml") + check_query_f(hge_ctx, self.dir() + "/author_student_role_insert_check_bio_success.yaml") def test_student_role_insert_check_bio_fail(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/author_student_role_insert_check_bio_fail.yaml") + check_query_f(hge_ctx, self.dir() + "/author_student_role_insert_check_bio_fail.yaml") def test_company_user_role_insert(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/company_user_role.yaml") + check_query_f(hge_ctx, self.dir() + "/company_user_role.yaml") def test_company_user_role_insert_on_conflict(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/company_user_role_on_conflict.yaml") + check_query_f(hge_ctx, self.dir() + "/company_user_role_on_conflict.yaml") def test_resident_user_role_insert(self, hge_ctx): check_query_f(hge_ctx, self.dir() + "/resident_user.yaml") @@ -125,7 +125,7 @@ def dir(cls): class TestGraphqlInsertConstraints(DefaultTestQueries): def test_address_not_null_constraint_err(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/address_not_null_constraint_error.yaml") + check_query_f(hge_ctx, self.dir() + "/address_not_null_constraint_error.yaml") def test_insert_unique_constraint_err(self, hge_ctx): check_query_f(hge_ctx, self.dir() + "/author_unique_constraint_error.yaml") @@ -236,16 +236,16 @@ def dir(cls): class TestGraphqlUpdateBasic(DefaultTestQueries): def test_set_author_name(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/author_set_name.yaml") + check_query_f(hge_ctx, self.dir() + "/author_set_name.yaml") def test_set_person_details(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_set_details.yaml") + check_query_f(hge_ctx, self.dir() + "/person_set_details.yaml") - def test_person_id_inc(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_inc.yaml") + def test_person_id_inc(self, hge_ctx): + check_query_f(hge_ctx, self.dir() + "/person_inc.yaml") def test_no_operator_err(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_error_no_operator.yaml") + check_query_f(hge_ctx, self.dir() + "/person_error_no_operator.yaml") @classmethod def dir(cls): @@ -255,22 +255,22 @@ def dir(cls): class TestGraphqlUpdateJsonB(DefaultTestQueries): def test_jsonb_append_object(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_append_object.yaml") + check_query_f(hge_ctx, self.dir() + "/person_append_object.yaml") def test_jsonb_append_array(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_append_array.yaml") + check_query_f(hge_ctx, self.dir() + "/person_append_array.yaml") def test_jsonb_prepend_array(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_prepend_array.yaml") + check_query_f(hge_ctx, self.dir() + "/person_prepend_array.yaml") def test_jsonb_delete_at_path(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_delete_at_path.yaml") + check_query_f(hge_ctx, self.dir() + "/person_delete_at_path.yaml") def test_jsonb_delete_array_element(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_delete_array_element.yaml") + check_query_f(hge_ctx, self.dir() + "/person_delete_array_element.yaml") def test_jsonb_delete_key(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_delete_key.yaml") + check_query_f(hge_ctx, self.dir() + "/person_delete_key.yaml") @classmethod def dir(cls): @@ -302,10 +302,10 @@ def dir(cls): class TestGraphqlDeleteBasic(DefaultTestQueries): def test_article_delete(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/article.yaml") + check_query_f(hge_ctx, self.dir() + "/article.yaml") def test_article_delete_returning(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/article_returning.yaml") + check_query_f(hge_ctx, self.dir() + "/article_returning.yaml") @classmethod def dir(cls): @@ -315,7 +315,7 @@ def dir(cls): class TestGraphqlDeleteConstraints(DefaultTestQueries): def test_author_delete_foreign_key_violation(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/author_foreign_key_violation.yaml") + check_query_f(hge_ctx, self.dir() + "/author_foreign_key_violation.yaml") @classmethod def dir(cls): @@ -325,7 +325,7 @@ def dir(cls): class TestGraphqlDeletePermissions(DefaultTestQueries): def test_author_can_delete_his_articles(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/author_can_delete_his_articles.yaml") + check_query_f(hge_ctx, self.dir() + "/author_can_delete_his_articles.yaml") def test_author_cannot_delete_other_users_articles(self, hge_ctx): check_query_f(hge_ctx, self.dir() + "/author_cannot_delete_other_users_articles.yaml") diff --git a/server/tests-py/test_subscriptions.py b/server/tests-py/test_subscriptions.py index 9fd15e9754132..9a2b5cc89af15 100644 --- a/server/tests-py/test_subscriptions.py +++ b/server/tests-py/test_subscriptions.py @@ -8,6 +8,8 @@ ''' Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_connection_init ''' + + def test_init_without_payload(hge_ctx): if hge_ctx.hge_key is not None: pytest.skip("Payload is needed when access key is set") @@ -18,9 +20,12 @@ def test_init_without_payload(hge_ctx): ev = hge_ctx.get_ws_event(3) assert ev['type'] == 'connection_ack', ev + ''' Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_connection_init ''' + + def test_init(hge_ctx): payload = {} if hge_ctx.hge_key is not None: @@ -37,6 +42,7 @@ def test_init(hge_ctx): ev = hge_ctx.get_ws_event(3) assert ev['type'] == 'connection_ack', ev + class TestSubscriptionBasic(object): @pytest.fixture(autouse=True) @@ -51,6 +57,7 @@ def transact(self, request, hge_ctx): ''' Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_connection_error ''' + def test_connection_error(self, hge_ctx): hge_ctx.ws.send("test") ev = hge_ctx.get_ws_event(3) @@ -59,6 +66,7 @@ def test_connection_error(self, hge_ctx): ''' Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_start ''' + def test_start(self, hge_ctx): query = """ subscription { @@ -85,6 +93,7 @@ def test_start(self, hge_ctx): ''' Refer https://github.com/apollographql/subscriptions-transport-ws/blob/01e0b2b65df07c52f5831cce5c858966ba095993/src/server.ts#L306 ''' + @pytest.mark.skip(reason="refer https://github.com/hasura/graphql-engine/pull/387#issuecomment-421343098") def test_start_duplicate(self, hge_ctx): self.test_start(hge_ctx) @@ -100,6 +109,7 @@ def test_stop_without_id(self, hge_ctx): ''' Refer https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_stop ''' + def test_stop(self, hge_ctx): obj = { 'type': 'stop', @@ -116,6 +126,7 @@ def test_start_after_stop(self, hge_ctx): ''' Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_complete ''' + def test_complete(self, hge_ctx): query = """ query { @@ -191,12 +202,12 @@ def test_live_queries(self, hge_ctx): hge_ctx.ws.send(json.dumps(obj)) ev = hge_ctx.get_ws_event(3) assert ev['type'] == 'data' and ev['id'] == obj['id'], ev - assert ev['payload']['data'] == {'hge_tests_test_t2': []} , ev['payload']['data'] + assert ev['payload']['data'] == {'hge_tests_test_t2': []}, ev['payload']['data'] assert isinstance(conf, list) == True, 'Not an list' for index, step in enumerate(conf): obj = { - 'id': '{}'.format(index+1), + 'id': '{}'.format(index + 1), 'payload': { 'query': step['query'] }, @@ -218,7 +229,8 @@ def test_live_queries(self, hge_ctx): ev = hge_ctx.get_ws_event(3) assert ev['type'] == 'data' and ev['id'] == 'live', ev assert ev['payload']['data'] == { - 'hge_tests_test_t2': expected_resp[step['name']]['returning'] if 'returning' in expected_resp[step['name']] else [] + 'hge_tests_test_t2': expected_resp[step['name']]['returning'] if 'returning' in expected_resp[ + step['name']] else [] }, ev['payload']['data'] # stop live operation @@ -230,9 +242,12 @@ def test_live_queries(self, hge_ctx): with pytest.raises(queue.Empty): ev = hge_ctx.get_ws_event(3) + ''' Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_connection_terminate ''' + + def test_connection_terminate(hge_ctx): obj = { 'type': 'connection_terminate' diff --git a/server/tests-py/test_v1_queries.py b/server/tests-py/test_v1_queries.py index 7ff35c7fa8ae6..6167ef7dd6a47 100644 --- a/server/tests-py/test_v1_queries.py +++ b/server/tests-py/test_v1_queries.py @@ -2,6 +2,7 @@ from validate import check_query_f from super_classes import DefaultTestSelectQueries, DefaultTestQueries + class TestV1General(DefaultTestQueries): def test_query_string_input_err(self, hge_ctx): @@ -17,6 +18,7 @@ def test_query_args_as_string_err(self, hge_ctx): def dir(cls): return "queries/v1/basic" + class TestV1SelectBasic(DefaultTestSelectQueries): def test_select_query_author(self, hge_ctx): @@ -250,25 +252,25 @@ def dir(cls): class TestV1UpdateBasic(DefaultTestQueries): def test_set_author_name(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/author_set_name.yaml") + check_query_f(hge_ctx, self.dir() + "/author_set_name.yaml") def test_set_person_details(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_set_details.yaml") + check_query_f(hge_ctx, self.dir() + "/person_set_details.yaml") - def test_person_id_inc(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_inc.yaml") + def test_person_id_inc(self, hge_ctx): + check_query_f(hge_ctx, self.dir() + "/person_inc.yaml") - def test_product_mul_price(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/product_mul_price.yaml") + def test_product_mul_price(self, hge_ctx): + check_query_f(hge_ctx, self.dir() + "/product_mul_price.yaml") - def test_product_set_default_price(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/product_set_default_price.yaml") + def test_product_set_default_price(self, hge_ctx): + check_query_f(hge_ctx, self.dir() + "/product_set_default_price.yaml") def test_no_operator_err(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_error_no_operator.yaml") + check_query_f(hge_ctx, self.dir() + "/person_error_no_operator.yaml") def test_no_where_clause_err(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/person_error_no_where_clause.yaml") + check_query_f(hge_ctx, self.dir() + "/person_error_no_where_clause.yaml") @classmethod def dir(cls): @@ -278,7 +280,7 @@ def dir(cls): class TestV1UpdatePermissions(DefaultTestQueries): def test_user_can_update_unpublished_article(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/user_can_update_unpublished_article.yaml") + check_query_f(hge_ctx, self.dir() + "/user_can_update_unpublished_article.yaml") def test_user_cannot_update_published_version_col(self, hge_ctx): check_query_f(hge_ctx, self.dir() + "/user_cannot_update_published_article_version.yaml") @@ -300,28 +302,28 @@ def dir(cls): class TestV1CountBasic(DefaultTestSelectQueries): def test_count_authors(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/count_authors.yaml") + check_query_f(hge_ctx, self.dir() + "/count_authors.yaml") def test_count_published_articles(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/count_published_articles.yaml") + check_query_f(hge_ctx, self.dir() + "/count_published_articles.yaml") def test_count_unpublished_articles(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/count_unpublished_articles.yaml") + check_query_f(hge_ctx, self.dir() + "/count_unpublished_articles.yaml") def test_count_distinct_authors_with_published_articles(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/count_distinct_authors_with_published_articles.yaml") + check_query_f(hge_ctx, self.dir() + "/count_distinct_authors_with_published_articles.yaml") def test_count_articles_registered_authors(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/count_articles_with_registered_authors.yaml") + check_query_f(hge_ctx, self.dir() + "/count_articles_with_registered_authors.yaml") def test_count_articles_non_registered_authors(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/count_articles_with_non_registered_authors.yaml") + check_query_f(hge_ctx, self.dir() + "/count_articles_with_non_registered_authors.yaml") def test_count_distinct_col_not_present_err(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/count_distinct_col_not_present_err.yaml") + check_query_f(hge_ctx, self.dir() + "/count_distinct_col_not_present_err.yaml") def test_count_distinct_authors_with_unpublished_articles(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/count_distinct_authors_with_unpublished_articles.yaml") + check_query_f(hge_ctx, self.dir() + "/count_distinct_authors_with_unpublished_articles.yaml") @classmethod def dir(cls): @@ -331,10 +333,10 @@ def dir(cls): class TestV1CountPermissions(DefaultTestSelectQueries): def test_count_user_has_no_select_permission_err(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/count_user_has_no_select_perm_error.yaml") + check_query_f(hge_ctx, self.dir() + "/count_user_has_no_select_perm_error.yaml") def test_count_other_users_unpublished_articles(self, hge_ctx): - check_query_f(hge_ctx, self.dir() + "/count_users_unpublished_articles.yaml") + check_query_f(hge_ctx, self.dir() + "/count_users_unpublished_articles.yaml") @classmethod def dir(cls): diff --git a/server/tests-py/test_version.py b/server/tests-py/test_version.py index b4e55b23f26fb..eb6d842b0f46d 100644 --- a/server/tests-py/test_version.py +++ b/server/tests-py/test_version.py @@ -2,6 +2,7 @@ import pytest + class TestServerVersion(object): def test_version(self, hge_ctx): diff --git a/server/tests-py/validate.py b/server/tests-py/validate.py index b8361f9fbd50f..31d0128626228 100644 --- a/server/tests-py/validate.py +++ b/server/tests-py/validate.py @@ -7,13 +7,14 @@ import jsondiff import jwt + def check_keys(keys, obj): for k in keys: assert k in obj, obj -def check_ev_payload_shape(ev_payload): - top_level_keys = [ "created_at", "event", "id", "table", "trigger"] +def check_ev_payload_shape(ev_payload): + top_level_keys = ["created_at", "event", "id", "table", "trigger"] check_keys(top_level_keys, ev_payload) event_keys = ["data", "op"] @@ -22,21 +23,24 @@ def check_ev_payload_shape(ev_payload): trigger_keys = ["id", "name"] check_keys(trigger_keys, ev_payload['trigger']) + def validate_event_payload(ev_payload, trig_name, table): check_ev_payload_shape(ev_payload) assert ev_payload['table'] == table, ev_payload assert ev_payload['trigger']['name'] == trig_name, ev_payload + def validate_event_headers(ev_headers, headers): for key, value in headers.items(): v = ev_headers.get(key) assert v == value, (key, v) + def validate_event_webhook(ev_webhook_path, webhook_path): assert ev_webhook_path == webhook_path -def check_event(hge_ctx, trig_name, table, operation, exp_ev_data, headers, webhook_path): +def check_event(hge_ctx, trig_name, table, operation, exp_ev_data, headers, webhook_path): ev_full = hge_ctx.get_event(3) validate_event_webhook(ev_full['path'], webhook_path) validate_event_headers(ev_full['headers'], headers) @@ -47,100 +51,107 @@ def check_event(hge_ctx, trig_name, table, operation, exp_ev_data, headers, webh def test_forbidden_when_access_key_reqd(hge_ctx, conf): - headers={} + headers = {} if 'headers' in conf: headers = conf['headers'] - #Test without access key - code, resp = hge_ctx.anyq( conf['url'], conf['query'], headers) - assert code == 401, "\n" + yaml.dump( { - "expected" : "Should be access denied as access key is not provided", - "actual" : { - "code" : code, - "response" : resp - } - } ) - - #Test with random access key + # Test without access key + code, resp = hge_ctx.anyq(conf['url'], conf['query'], headers) + assert code == 401, "\n" + yaml.dump({ + "expected": "Should be access denied as access key is not provided", + "actual": { + "code": code, + "response": resp + } + }) + + # Test with random access key headers['X-Hasura-Access-Key'] = base64.b64encode(os.urandom(30)) - code, resp = hge_ctx.anyq( conf['url'], conf['query'], headers) - assert code == 401, "\n" + yaml.dump( { - "expected" : "Should be access denied as an incorrect access key is provided", - "actual" : { - "code" : code, - "response" : resp - } - } ) + code, resp = hge_ctx.anyq(conf['url'], conf['query'], headers) + assert code == 401, "\n" + yaml.dump({ + "expected": "Should be access denied as an incorrect access key is provided", + "actual": { + "code": code, + "response": resp + } + }) + def test_forbidden_webhook(hge_ctx, conf): + h = {'Authorization': 'Bearer ' + base64.b64encode(base64.b64encode(os.urandom(30))).decode('utf-8')} + code, resp = hge_ctx.anyq(conf['url'], conf['query'], h) + assert code == 401, "\n" + yaml.dump({ + "expected": "Should be access denied as it is denied from webhook", + "actual": { + "code": code, + "response": resp + } + }) - h = { 'Authorization' : 'Bearer ' + base64.b64encode(base64.b64encode(os.urandom(30))).decode('utf-8') } - code, resp = hge_ctx.anyq( conf['url'], conf['query'], h ) - assert code == 401, "\n" + yaml.dump( { - "expected" : "Should be access denied as it is denied from webhook", - "actual" : { - "code" : code, - "response" : resp - } - } ) def check_query(hge_ctx, conf, add_auth=True): - headers={} + headers = {} if 'headers' in conf: headers = conf['headers'] if add_auth: if hge_ctx.hge_jwt_key is not None and len(headers) > 0 and 'X-Hasura-Role' in headers: - hClaims=dict() - hClaims['X-Hasura-Allowed-Roles']=[headers['X-Hasura-Role']] - hClaims['X-Hasura-Default-Role']=headers['X-Hasura-Role'] + hClaims = dict() + hClaims['X-Hasura-Allowed-Roles'] = [headers['X-Hasura-Role']] + hClaims['X-Hasura-Default-Role'] = headers['X-Hasura-Role'] for key in headers: if key != 'X-Hasura-Role': - hClaims[key]=headers[key] - claim={ + hClaims[key] = headers[key] + claim = { "sub": "foo", "name": "bar", "https://hasura.io/jwt/claims": hClaims } - headers['Authorization'] = 'Bearer ' + jwt.encode(claim, hge_ctx.hge_jwt_key, algorithm='RS512').decode('UTF-8') + headers['Authorization'] = 'Bearer ' + jwt.encode(claim, hge_ctx.hge_jwt_key, algorithm='RS512').decode( + 'UTF-8') if hge_ctx.hge_webhook is not None and len(headers) > 0: if not hge_ctx.webhook_insecure: test_forbidden_webhook(hge_ctx, conf) headers['X-Hasura-Auth-Mode'] = 'webhook' headers_new = dict() - headers_new['Authorization'] = 'Bearer ' + base64.b64encode(json.dumps(headers).encode('utf-8')).decode('utf-8') + headers_new['Authorization'] = 'Bearer ' + base64.b64encode(json.dumps(headers).encode('utf-8')).decode( + 'utf-8') headers = headers_new - elif (hge_ctx.hge_webhook is not None or hge_ctx.hge_jwt_key is not None) and hge_ctx.hge_key is not None and len(headers) == 0: + elif ( + hge_ctx.hge_webhook is not None or hge_ctx.hge_jwt_key is not None) and hge_ctx.hge_key is not None and len( + headers) == 0: headers['X-Hasura-Access-Key'] = hge_ctx.hge_key elif hge_ctx.hge_key is not None and hge_ctx.hge_webhook is None and hge_ctx.hge_jwt_key is None: test_forbidden_when_access_key_reqd(hge_ctx, conf) headers['X-Hasura-Access-Key'] = hge_ctx.hge_key - code, resp = hge_ctx.anyq( conf['url'], conf['query'], headers) - print (headers) + code, resp = hge_ctx.anyq(conf['url'], conf['query'], headers) + print(headers) assert code == conf['status'], resp if 'response' in conf: - assert json_ordered(resp) == json_ordered(conf['response']) , yaml.dump( { - 'response' : resp, - 'expected' : conf['response'], + assert json_ordered(resp) == json_ordered(conf['response']), yaml.dump({ + 'response': resp, + 'expected': conf['response'], 'diff': jsondiff.diff(conf['response'], resp) - } ) + }) return code, resp + def check_query_f(hge_ctx, f, add_auth=True): hge_ctx.may_skip_test_teardown = False with open(f) as c: conf = yaml.safe_load(c) if isinstance(conf, list): for sconf in conf: - check_query( hge_ctx, sconf) + check_query(hge_ctx, sconf) else: if conf['status'] != 200: hge_ctx.may_skip_test_teardown = True - check_query( hge_ctx, conf, add_auth ) + check_query(hge_ctx, conf, add_auth) + def json_ordered(obj): if isinstance(obj, dict):