graphql-engine/server/tests-py/test_config_api.py
Samir Talwar 26e03a07bb server/tests-py: Parallelize JWT tests.
This rewrites the JWT tests to generate and specify the secrets per test class, and to provide the server configuration to the HGE fixture.

It covers the tests in:

  - *test_jwt.py*
  - *test_jwt_claims_map.py*
  - *test_config_api.py*
  - *test_graphql_queries.py* (just a couple here)

This does reduce the number of code paths exercised with JWT, as we were previously running *all* tests with JWT tokens. However, this seems excessive; we don't need to tread every code path, just enough to ensure we handle the tokens appropriately. I believe that the test coverage in *test_jwt.py* does this well enough (though I'd prefer if we moved the coverage lower down in the stack as unit tests).

These tests were configured in multiple different ways by *test-server.sh*; this configuration is now moved to test subclasses within the various files. This results in a bit of duplication.

Unfortunately, the tests would ideally use parameterization rather than subclassing, but that doesn't work because of `hge_fixture_env`, which creates a "soft" dependency between the environment variables and `hge_server`. Parameterizing the former *should* force the latter to be recreated for each new set of environment variables, but `hge_server` isn't actually aware there's a dependency.

It currently looks like this adds lines of code; we'll more than make up for it when we delete the relevant lines from *test-server.sh*. I am not doing that here because I plan on deleting the whole file in a subsequent changeset.

[NDAT-538]: https://hasurahq.atlassian.net/browse/NDAT-538?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8803
GitOrigin-RevId: f7f2caa62de0b0a45e42964b69a8ae73d1575fe8
2023-04-19 10:30:21 +00:00

184 lines
6.2 KiB
Python

import pytest
class TestConfigApiWithAnInsecureServer:
def test_responds_correctly(self, hge_ctx):
headers = {
'x-hasura-role': 'admin',
}
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config', headers=headers)
assert resp.status_code == 200, resp
body = resp.json()
print('Body:', body)
assert body['is_admin_secret_set'] == False
assert body['is_auth_hook_set'] == False
assert body['is_jwt_set'] == False
assert body['jwt'] == []
def test_rejects_an_invalid_role(self, hge_ctx):
headers = {
'x-hasura-role': 'user',
}
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config', headers=headers)
assert resp.status_code == 400, resp
@pytest.mark.admin_secret
class TestConfigApiWithAdminSecret:
def test_responds_correctly(self, hge_ctx, hge_key):
headers = {
'x-hasura-role': 'admin',
'x-hasura-admin-secret': hge_key,
}
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config', headers=headers)
assert resp.status_code == 200, resp
body = resp.json()
print('Body:', body)
assert body['is_admin_secret_set'] == True
assert body['is_auth_hook_set'] == False
assert body['is_jwt_set'] == False
assert body['jwt'] == []
def test_rejects_an_invalid_role(self, hge_ctx, hge_key):
headers = {
'x-hasura-role': 'user',
'x-hasura-admin-secret': hge_key,
}
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config', headers=headers)
assert resp.status_code == 400, resp
def test_request_fails_without_auth_headers(self, hge_ctx):
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config')
assert (resp.status_code == 401) or (resp.status_code == 400)
@pytest.mark.admin_secret
@pytest.mark.usefixtures('auth_hook')
class TestConfigApiWithAuthHook:
def test_responds_correctly(self, hge_ctx, hge_key):
headers = {
'x-hasura-role': 'admin',
'x-hasura-admin-secret': hge_key,
}
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config', headers=headers)
assert resp.status_code == 200, resp
body = resp.json()
print('Body:', body)
assert body['is_admin_secret_set'] == True
assert body['is_auth_hook_set'] == True
assert body['is_jwt_set'] == False
assert body['jwt'] == []
def test_rejects_an_invalid_role(self, hge_ctx, hge_key):
headers = {
'x-hasura-role': 'user',
'x-hasura-admin-secret': hge_key,
}
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config', headers=headers)
assert resp.status_code == 400, resp
def test_request_fails_without_auth_headers(self, hge_ctx):
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config')
assert (resp.status_code == 401) or (resp.status_code == 400)
@pytest.mark.admin_secret
@pytest.mark.usefixtures('jwt_configuration')
@pytest.mark.jwt('ed25519')
class TestConfigApiWithJwtAndNoClaims:
def test_rejects_an_invalid_role(self, hge_ctx, hge_key):
headers = {
'x-hasura-role': 'user',
'x-hasura-admin-secret': hge_key,
}
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config', headers=headers)
assert resp.status_code == 400, resp
def test_responds_correctly(self, hge_ctx, hge_key):
headers = {
'x-hasura-role': 'admin',
'x-hasura-admin-secret': hge_key,
}
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config', headers=headers)
assert resp.status_code == 200, resp
body = resp.json()
print('Body:', body)
assert body['is_admin_secret_set'] == True
assert body['is_auth_hook_set'] == False
assert body['is_jwt_set'] == True
assert body['jwt'] == [
{
'claims_format': 'json',
'claims_map': None,
'claims_namespace': 'https://hasura.io/jwt/claims',
}
]
def test_request_fails_without_auth_headers(self, hge_ctx):
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config')
assert (resp.status_code == 401) or (resp.status_code == 400)
@pytest.mark.admin_secret
@pytest.mark.usefixtures('jwt_configuration')
@pytest.mark.jwt('ed25519', {
'claims_format': 'stringified_json',
})
class TestConfigApiWithJwtAndClaimsFormat:
def test_responds_correctly(self, hge_ctx, hge_key):
headers = {
'x-hasura-role': 'admin',
'x-hasura-admin-secret': hge_key,
}
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config', headers=headers)
assert resp.status_code == 200, resp
body = resp.json()
print('Body:', body)
assert body['is_admin_secret_set'] == True
assert body['is_auth_hook_set'] == False
assert body['is_jwt_set'] == True
assert body['jwt'] == [
{
'claims_format': 'stringified_json',
'claims_map': None,
'claims_namespace': 'https://hasura.io/jwt/claims',
}
]
@pytest.mark.admin_secret
@pytest.mark.usefixtures('jwt_configuration')
@pytest.mark.jwt('ed25519', {
'claims_namespace': 'https://example.org/jwt/claims',
'claims_format': 'stringified_json',
})
class TestConfigApiWithJwtAndClaimsNamespace:
def test_responds_correctly(self, hge_ctx, hge_key):
headers = {
'x-hasura-role': 'admin',
'x-hasura-admin-secret': hge_key,
}
resp = hge_ctx.http.get(hge_ctx.hge_url + '/v1alpha1/config', headers=headers)
assert resp.status_code == 200, resp
body = resp.json()
print('Body:', body)
assert body['is_admin_secret_set'] == True
assert body['is_auth_hook_set'] == False
assert body['is_jwt_set'] == True
assert body['jwt'] == [
{
'claims_format': 'stringified_json',
'claims_map': None,
'claims_namespace': 'https://example.org/jwt/claims',
}
]