mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-18 21:12:09 +03:00
dc4a286c64
## Description This PR adds all the scaffolding for tests that require remote servers. It is mostly a refactor of `Feature`; where we listed for each test a list of individual backends, we now provide a list of `Context`s, that allows for tests to specify not only how it should be setup, but also what state needs to be carried around throughout the test. This will be useful when launching custom remote servers. Additionally, this PR: - cleans the way we generate logs in the engine as part of the tests - cleans the cabal file - introduce a few more helpers for sending commands to the engine (such as `postMetadata_`) - allows for headers in queries sent to the engine (to support permissions tests) - adds basic code to start / stop a "remote" server This PR is a pre-requisite of #3567. PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3573 Co-authored-by: jkachmar <8461423+jkachmar@users.noreply.github.com> GitOrigin-RevId: 05f808c6b85729dbb3ea6648c3e10a3c16b641ef
413 lines
7.8 KiB
Haskell
413 lines
7.8 KiB
Haskell
{-# LANGUAGE QuasiQuotes #-}
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
|
|
-- | Test querying an entity for a couple fields.
|
|
module Test.BasicFieldsSpec (spec) where
|
|
|
|
import Harness.Backend.BigQuery qualified as BigQuery
|
|
import Harness.Backend.Citus qualified as Citus
|
|
import Harness.Backend.Mysql qualified as Mysql
|
|
import Harness.Backend.Postgres qualified as Postgres
|
|
import Harness.Backend.Sqlserver qualified as Sqlserver
|
|
import Harness.GraphqlEngine qualified as GraphqlEngine
|
|
import Harness.Quoter.Graphql (graphql)
|
|
import Harness.Quoter.Sql (sql)
|
|
import Harness.Quoter.Yaml (shouldReturnYaml, yaml)
|
|
import Harness.State (State)
|
|
import Harness.Test.Feature qualified as Feature
|
|
import Test.Hspec (SpecWith, it)
|
|
import Prelude
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Preamble
|
|
|
|
spec :: SpecWith State
|
|
spec =
|
|
Feature.run
|
|
[ Feature.Context
|
|
{ name = "MySQL",
|
|
setup = mysqlSetup,
|
|
teardown = mysqlTeardown,
|
|
options = Feature.defaultOptions
|
|
},
|
|
Feature.Context
|
|
{ name = "PostgreSQL",
|
|
setup = postgresSetup,
|
|
teardown = postgresTeardown,
|
|
options = Feature.defaultOptions
|
|
},
|
|
Feature.Context
|
|
{ name = "Citus",
|
|
setup = citusSetup,
|
|
teardown = citusTeardown,
|
|
options = Feature.defaultOptions
|
|
},
|
|
Feature.Context
|
|
{ name = "SQLServer",
|
|
setup = sqlserverSetup,
|
|
teardown = sqlserverTeardown,
|
|
options = Feature.defaultOptions
|
|
},
|
|
Feature.Context
|
|
{ name = "BigQuery",
|
|
setup = bigquerySetup,
|
|
teardown = bigqueryTeardown,
|
|
options =
|
|
Feature.Options
|
|
{ stringifyNumbers = True
|
|
}
|
|
}
|
|
]
|
|
tests
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- MySQL backend
|
|
|
|
mysqlSetup :: State -> IO ()
|
|
mysqlSetup state = do
|
|
-- Clear and reconfigure the metadata
|
|
GraphqlEngine.setSource state Mysql.defaultSourceMetadata
|
|
|
|
-- Setup tables
|
|
Mysql.run_
|
|
[sql|
|
|
CREATE TABLE hasura.author
|
|
(
|
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
name VARCHAR(45) UNIQUE KEY
|
|
);
|
|
|]
|
|
Mysql.run_
|
|
[sql|
|
|
INSERT INTO hasura.author
|
|
(name)
|
|
VALUES
|
|
( 'Author 1'),
|
|
( 'Author 2');
|
|
|]
|
|
|
|
-- Track the tables
|
|
GraphqlEngine.postMetadata_
|
|
state
|
|
[yaml|
|
|
type: mysql_track_table
|
|
args:
|
|
source: mysql
|
|
table:
|
|
schema: hasura
|
|
name: author
|
|
|]
|
|
|
|
mysqlTeardown :: (State, ()) -> IO ()
|
|
mysqlTeardown _ = do
|
|
Mysql.run_
|
|
[sql|
|
|
DROP TABLE hasura.author;
|
|
|]
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- PostgreSQL backend
|
|
|
|
postgresSetup :: State -> IO ()
|
|
postgresSetup state = do
|
|
-- Clear and reconfigure the metadata
|
|
GraphqlEngine.setSource state Postgres.defaultSourceMetadata
|
|
|
|
-- Setup tables
|
|
Postgres.run_
|
|
[sql|
|
|
CREATE TABLE hasura.author
|
|
(
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(45) UNIQUE
|
|
);
|
|
|]
|
|
Postgres.run_
|
|
[sql|
|
|
INSERT INTO hasura.author
|
|
(name)
|
|
VALUES
|
|
( 'Author 1'),
|
|
( 'Author 2');
|
|
|]
|
|
|
|
-- Track the tables
|
|
GraphqlEngine.postMetadata_
|
|
state
|
|
[yaml|
|
|
type: postgres_track_table
|
|
args:
|
|
source: postgres
|
|
table:
|
|
schema: hasura
|
|
name: author
|
|
|]
|
|
|
|
postgresTeardown :: (State, ()) -> IO ()
|
|
postgresTeardown _ = do
|
|
Postgres.run_
|
|
[sql|
|
|
DROP TABLE hasura.author;
|
|
|]
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Citus backend
|
|
|
|
citusSetup :: State -> IO ()
|
|
citusSetup state = do
|
|
-- Clear and reconfigure the metadata
|
|
GraphqlEngine.setSource state Citus.defaultSourceMetadata
|
|
|
|
-- Setup tables
|
|
Citus.run_
|
|
[sql|
|
|
CREATE TABLE hasura.author
|
|
(
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(45) UNIQUE
|
|
);
|
|
|]
|
|
Citus.run_
|
|
[sql|
|
|
INSERT INTO hasura.author
|
|
(name)
|
|
VALUES
|
|
( 'Author 1'),
|
|
( 'Author 2');
|
|
|]
|
|
|
|
-- Track the tables
|
|
GraphqlEngine.postMetadata_
|
|
state
|
|
[yaml|
|
|
type: citus_track_table
|
|
args:
|
|
source: citus
|
|
table:
|
|
schema: hasura
|
|
name: author
|
|
|]
|
|
|
|
citusTeardown :: (State, ()) -> IO ()
|
|
citusTeardown _ = do
|
|
Citus.run_
|
|
[sql|
|
|
DROP TABLE IF EXISTS hasura.author;
|
|
|]
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- SQL Server backend
|
|
|
|
sqlserverSetup :: State -> IO ()
|
|
sqlserverSetup state = do
|
|
-- Clear and reconfigure the metadata
|
|
GraphqlEngine.setSource state Sqlserver.defaultSourceMetadata
|
|
|
|
-- Setup tables
|
|
Sqlserver.run_
|
|
[sql|
|
|
CREATE TABLE hasura.author
|
|
(
|
|
id INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED,
|
|
name NVARCHAR(45) NOT NULL UNIQUE NONCLUSTERED
|
|
);
|
|
|]
|
|
Sqlserver.run_
|
|
[sql|
|
|
INSERT INTO hasura.author
|
|
(name)
|
|
VALUES
|
|
('Author 1'),
|
|
('Author 2');
|
|
|]
|
|
|
|
-- Track the tables
|
|
GraphqlEngine.postMetadata_
|
|
state
|
|
[yaml|
|
|
type: mssql_track_table
|
|
args:
|
|
source: mssql
|
|
table:
|
|
schema: hasura
|
|
name: author
|
|
|]
|
|
|
|
sqlserverTeardown :: (State, ()) -> IO ()
|
|
sqlserverTeardown _ = do
|
|
Sqlserver.run_
|
|
[sql|
|
|
DROP TABLE hasura.author;
|
|
|]
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- BigQuery backend
|
|
|
|
bigquerySetup :: State -> IO ()
|
|
bigquerySetup state = do
|
|
-- Clear and reconfigure the metadata
|
|
serviceAccount <- BigQuery.getServiceAccount
|
|
projectId <- BigQuery.getProjectId
|
|
GraphqlEngine.postMetadata_
|
|
state
|
|
[yaml|
|
|
type: replace_metadata
|
|
args:
|
|
version: 3
|
|
sources:
|
|
- name: bigquery
|
|
kind: bigquery
|
|
tables: []
|
|
configuration:
|
|
service_account: *serviceAccount
|
|
project_id: *projectId
|
|
datasets: [hasura]
|
|
|]
|
|
|
|
-- Setup tables
|
|
BigQuery.run_
|
|
serviceAccount
|
|
projectId
|
|
[sql|
|
|
CREATE TABLE hasura.author
|
|
(
|
|
id INT64,
|
|
name STRING
|
|
);
|
|
|]
|
|
BigQuery.run_
|
|
serviceAccount
|
|
projectId
|
|
[sql|
|
|
INSERT INTO hasura.author
|
|
(id, name)
|
|
VALUES
|
|
(1, 'Author 1'),
|
|
(2, 'Author 2');
|
|
|]
|
|
|
|
-- Track the tables
|
|
GraphqlEngine.postMetadata_
|
|
state
|
|
[yaml|
|
|
type: bigquery_track_table
|
|
args:
|
|
source: bigquery
|
|
table:
|
|
dataset: hasura
|
|
name: author
|
|
|]
|
|
|
|
bigqueryTeardown :: (State, ()) -> IO ()
|
|
bigqueryTeardown _ = do
|
|
serviceAccount <- BigQuery.getServiceAccount
|
|
projectId <- BigQuery.getProjectId
|
|
BigQuery.run_
|
|
serviceAccount
|
|
projectId
|
|
[sql|
|
|
DROP TABLE hasura.author;
|
|
|]
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Tests
|
|
|
|
tests :: Feature.Options -> SpecWith State
|
|
tests opts = do
|
|
it "Author fields" $ \state ->
|
|
shouldReturnYaml
|
|
opts
|
|
( GraphqlEngine.postGraphql
|
|
state
|
|
[graphql|
|
|
query {
|
|
hasura_author(order_by:[{id:asc}]) {
|
|
name
|
|
id
|
|
}
|
|
}
|
|
|]
|
|
)
|
|
[yaml|
|
|
data:
|
|
hasura_author:
|
|
- name: Author 1
|
|
id: 1
|
|
- name: Author 2
|
|
id: 2
|
|
|]
|
|
it "Use operationName" $ \state ->
|
|
shouldReturnYaml
|
|
opts
|
|
( GraphqlEngine.postGraphqlYaml
|
|
state
|
|
[yaml|
|
|
operationName: chooseThisOne
|
|
query: |
|
|
query ignoreThisOne {
|
|
MyQuery {
|
|
name
|
|
}
|
|
}
|
|
query chooseThisOne {
|
|
hasura_author(order_by:[{id:asc}]) {
|
|
id
|
|
name
|
|
}
|
|
}
|
|
|]
|
|
)
|
|
[yaml|
|
|
data:
|
|
hasura_author:
|
|
- name: Author 1
|
|
id: 1
|
|
- name: Author 2
|
|
id: 2
|
|
|]
|
|
it "Missing field" $ \state -> do
|
|
shouldReturnYaml
|
|
opts
|
|
( GraphqlEngine.postGraphql
|
|
state
|
|
[graphql|
|
|
query {
|
|
hasura_author {
|
|
id
|
|
name
|
|
notPresentCol
|
|
}
|
|
}
|
|
|]
|
|
)
|
|
[yaml|
|
|
errors:
|
|
- extensions:
|
|
code: validation-failed
|
|
path: $.selectionSet.hasura_author.selectionSet.notPresentCol
|
|
message: |-
|
|
field "notPresentCol" not found in type: 'hasura_author'
|
|
|]
|
|
it "Missing table" $ \state ->
|
|
shouldReturnYaml
|
|
opts
|
|
( GraphqlEngine.postGraphql
|
|
state
|
|
[graphql|
|
|
query {
|
|
random {
|
|
id
|
|
name
|
|
}
|
|
}
|
|
|]
|
|
)
|
|
[yaml|
|
|
errors:
|
|
- extensions:
|
|
code: validation-failed
|
|
path: $.selectionSet.random
|
|
message: |-
|
|
field "random" not found in type: 'query_root'
|
|
|]
|