text: #!/usr/bin/env python3
  
  import pytest
  import time
  
  from validate import check_query_f, check_query
  
  """
  TODO:- Test Actions metadata
  """
  
  use_action_fixtures = pytest.mark.usefixtures(
      "actions_fixture",
      'per_class_db_schema_for_mutation_tests',
      'per_method_db_data_for_mutation_tests'
  )
  
  @pytest.mark.parametrize("transport", ['http', 'websocket'])
  @use_action_fixtures
  class TestActionsSyncWebsocket:
  
      @classmethod
      def dir(cls):
          return 'queries/actions/sync'
  
      def test_create_user_fail(self, hge_ctx, transport):
          check_query_f(hge_ctx, self.dir() + '/create_user_fail.yaml', transport)
  
      def test_create_user_success(self, hge_ctx, transport):
          check_query_f(hge_ctx, self.dir() + '/create_user_success.yaml', transport)
  
      def test_create_users_fail(self, hge_ctx, transport):
          check_query_f(hge_ctx, self.dir() + '/create_users_fail.yaml', transport)
  
      def test_create_users_success(self, hge_ctx, transport):
          check_query_f(hge_ctx, self.dir() + '/create_users_success.yaml', transport)
  
  @use_action_fixtures
  class TestActionsSync:
  
      @classmethod
      def dir(cls):
          return 'queries/actions/sync'
  
      def test_invalid_webhook_response(self, hge_ctx):
          check_query_f(hge_ctx, self.dir() + '/invalid_webhook_response.yaml')
  
      def test_expecting_object_response(self, hge_ctx):
          check_query_f(hge_ctx, self.dir() + '/expecting_object_response.yaml')
  
      def test_expecting_array_response(self, hge_ctx):
          check_query_f(hge_ctx, self.dir() + '/expecting_array_response.yaml')
  
      # Webhook response validation tests. See https://github.com/hasura/graphql-engine/issues/3977
      def test_mirror_action_not_null(self, hge_ctx):
          check_query_f(hge_ctx, self.dir() + '/mirror_action_not_null.yaml')
  
      def test_mirror_action_unexpected_field(self, hge_ctx):
          check_query_f(hge_ctx, self.dir() + '/mirror_action_unexpected_field.yaml')
  
      def test_mirror_action_no_field(self, hge_ctx):
          check_query_f(hge_ctx, self.dir() + '/mirror_action_no_field.yaml')
  
      def test_mirror_action_success(self, hge_ctx):
          check_query_f(hge_ctx, self.dir() + '/mirror_action_success.yaml')
  
  def mk_headers_with_secret(hge_ctx, headers={}):
      admin_secret = hge_ctx.hge_key
      if admin_secret:
          headers['X-Hasura-Admin-Secret'] = admin_secret
      return headers
  
  @use_action_fixtures
  class TestActionsSyncResponseHeaders:
  
      @classmethod
      def dir(cls):
          return 'queries/actions/sync'
  
      # See https://github.com/hasura/graphql-engine/issues/4021
      def test_set_cookie_header(self, hge_ctx):
          mutation = '''
            mutation {
              create_user(email: "clarke@gmail.com", name: "Clarke"){
                id
              }
            }
          '''
          query = {
              'query': mutation,
              'variables': {}
          }
          status, resp, resp_headers = hge_ctx.anyq('/v1/graphql', query, mk_headers_with_secret(hge_ctx))
          assert status == 200, resp
          assert 'data' in resp, resp
          assert ('Set-Cookie' in resp_headers and
                  resp_headers['Set-Cookie'] == 'abcd'), resp_headers
  
  
  @use_action_fixtures
  class TestActionsAsync:
      @classmethod
      def dir(cls):
          return 'queries/actions/async'
  
      def test_create_user_fail(self, hge_ctx):
          graphql_mutation = '''
          mutation {
            create_user(email: "random-email", name: "Clarke")
          }
          '''
          query = {
              'query': graphql_mutation,
              'variables': {}
          }
          status, resp, _ = hge_ctx.anyq('/v1/graphql', query, mk_headers_with_secret(hge_ctx))
          assert status == 200, resp
          assert 'data' in resp
          action_id = resp['data']['create_user']
          time.sleep(3)
  
          query_async = '''
          query ($action_id: uuid!){
            create_user(id: $action_id){
              id
              errors
            }
          }
          '''
          query = {
              'query': query_async,
              'variables': {
                  'action_id': action_id
              }
          }
          response = {
              'data': {
                  'create_user': {
                      'id': action_id,
                      'errors': {
                          'code': 'invalid-email',
                          'path': '$',
                          'error': 'Given email address is not valid'
                      }
                  }
              }
          }
          conf = {
              'url': '/v1/graphql',
              'headers': {},
              'query': query,
              'status': 200,
              'response': response
          }
          check_query(hge_ctx, conf)
  
      def test_create_user_success(self, hge_ctx):
          graphql_mutation = '''
          mutation {
            create_user(email: "clarke@hasura.io", name: "Clarke")
          }
          '''
          query = {
              'query': graphql_mutation,
              'variables': {}
          }
          status, resp, _ = hge_ctx.anyq('/v1/graphql', query, mk_headers_with_secret(hge_ctx))
          assert status == 200, resp
          assert 'data' in resp
          action_id = resp['data']['create_user']
          time.sleep(3)
  
          query_async = '''
          query ($action_id: uuid!){
            create_user(id: $action_id){
              __typename
              id
              output {
                __typename
                id
                user {
                  __typename
                  name
                  email
                  is_admin
                }
              }
            }
          }
          '''
          query = {
              'query': query_async,
              'variables': {
                  'action_id': action_id
              }
          }
          response = {
              'data': {
                  'create_user': {
                      '__typename': 'create_user',
                      'id': action_id,
                      'output': {
                          '__typename': 'UserId',
                          'id': 1,
                          'user': {
                              '__typename': 'user',
                              'name': 'Clarke',
                              'email': 'clarke@hasura.io',
                              'is_admin': False
                          }
                      }
                  }
              }
          }
          conf = {
              'url': '/v1/graphql',
              'headers': {},
              'query': query,
              'status': 200,
              'response': response
          }
          check_query(hge_ctx, conf)
  
      def test_create_user_roles(self, hge_ctx):
          graphql_mutation = '''
          mutation {
            create_user(email: "blake@hasura.io", name: "Blake")
          }
          '''
          query = {
              'query': graphql_mutation,
              'variables': {}
          }
          headers_user_1 = mk_headers_with_secret(hge_ctx, {
              'X-Hasura-Role': 'user',
              'X-Hasura-User-Id': '1'
          })
          # create action with user-id 1
          status, resp, headers = hge_ctx.anyq('/v1/graphql', query, headers_user_1)
          assert status == 200, resp
          assert 'data' in resp
          action_id = resp['data']['create_user']
          time.sleep(3)
  
          query_async = '''
          query ($action_id: uuid!){
            create_user(id: $action_id){
              id
              output {
                id
              }
            }
          }
          '''
          query = {
              'query': query_async,
              'variables': {
                  'action_id': action_id
              }
          }
  
          headers_user_2 = mk_headers_with_secret(hge_ctx, {
              'X-Hasura-Role': 'user',
              'X-Hasura-User-Id': '2'
          })
          conf_user_2 = {
              'url': '/v1/graphql',
              'headers': headers_user_2,
              'query': query,
              'status': 200,
              'response': {
                  'data': {
                      'create_user': None # User 2 shouldn't able to access the action
                  }
              }
          }
          # Query the action as user-id 2
          # Make request without auth using admin_secret
          check_query(hge_ctx, conf_user_2, add_auth = False)
  
          conf_user_1 = {
              'url': '/v1/graphql',
              'headers': headers_user_1,
              'query': query,
              'status': 200,
              'response': {
                  'data': {
                      'create_user': {
                          'id': action_id,
                          'output': {
                              'id': 1
                          }
                      }
                  }
              }
          }
          # Query the action as user-id 1
          # Make request without auth using admin_secret
          check_query(hge_ctx, conf_user_1, add_auth = False)
  