mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-25 00:13:11 +03:00
0922a3bb24
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5451 GitOrigin-RevId: 8847af09a83293c619326d22209289397911bc5a
239 lines
8.1 KiB
Haskell
239 lines
8.1 KiB
Haskell
{-# LANGUAGE QuasiQuotes #-}
|
|
{-# LANGUAGE ViewPatterns #-}
|
|
|
|
-- | Test that the event triggers works well when the extensions are installed in
|
|
-- in a different schema
|
|
module Test.EventTrigger.EventTriggersExtensionSchemaSpec (spec) where
|
|
|
|
import Control.Concurrent.Chan qualified as Chan
|
|
import Data.List.NonEmpty qualified as NE
|
|
import Harness.Backend.Postgres qualified as Postgres
|
|
import Harness.Constants (postgresqlConnectionString)
|
|
import Harness.GraphqlEngine qualified as GraphqlEngine
|
|
import Harness.Quoter.Yaml
|
|
import Harness.Test.Fixture qualified as Fixture
|
|
import Harness.Test.Schema (Table (..), table)
|
|
import Harness.Test.Schema qualified as Schema
|
|
import Harness.TestEnvironment (TestEnvironment, stopServer)
|
|
import Harness.Webhook qualified as Webhook
|
|
import Harness.Yaml (shouldBeYaml, shouldReturnYaml)
|
|
import Hasura.Prelude
|
|
import System.Timeout (timeout)
|
|
import Test.HUnit.Base (assertFailure)
|
|
import Test.Hspec (SpecWith, describe, it)
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Preamble
|
|
|
|
spec :: SpecWith TestEnvironment
|
|
spec =
|
|
Fixture.runWithLocalTestEnvironment
|
|
( NE.fromList
|
|
[ (Fixture.fixture $ Fixture.Backend Fixture.Postgres)
|
|
{ -- setup the webhook server as the local test environment,
|
|
-- so that the server can be referenced while testing
|
|
Fixture.mkLocalTestEnvironment = webhookServerMkLocalTestEnvironment,
|
|
Fixture.setupTeardown = \testEnv ->
|
|
[ Fixture.SetupAction
|
|
{ Fixture.setupAction = postgresSetup testEnv,
|
|
Fixture.teardownAction = \_ -> postgresTeardown testEnv
|
|
}
|
|
]
|
|
}
|
|
]
|
|
)
|
|
tests
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- * Backend
|
|
|
|
-- ** Schema
|
|
|
|
authorsTable :: Text -> Schema.Table
|
|
authorsTable tableName =
|
|
(table tableName)
|
|
{ tableColumns =
|
|
[ Schema.column "id" Schema.TInt,
|
|
Schema.column "name" Schema.TStr
|
|
],
|
|
tablePrimaryKey = ["id"],
|
|
tableData =
|
|
[ [Schema.VInt 1, Schema.VStr "Author 1"],
|
|
[Schema.VInt 2, Schema.VStr "Author 2"]
|
|
]
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Tests
|
|
|
|
tests :: Fixture.Options -> SpecWith (TestEnvironment, (GraphqlEngine.Server, Webhook.EventsQueue))
|
|
tests opts = do
|
|
checkEventTriggerWhenExtensionInDifferentSchema opts
|
|
|
|
checkEventTriggerWhenExtensionInDifferentSchema :: Fixture.Options -> SpecWith (TestEnvironment, (GraphqlEngine.Server, Webhook.EventsQueue))
|
|
checkEventTriggerWhenExtensionInDifferentSchema opts =
|
|
describe "event triggers should work when extensions are created in different schema using 'extensions_schema'" do
|
|
it "check: inserting a new row invokes a event trigger" $
|
|
\(testEnvironment, (_, (Webhook.EventsQueue eventsQueue))) -> do
|
|
let insertQuery =
|
|
[yaml|
|
|
type: run_sql
|
|
args:
|
|
source: hge_test
|
|
sql: "INSERT INTO authors (id, name) values (3, 'john')"
|
|
|]
|
|
|
|
expectedResponse =
|
|
[yaml|
|
|
result_type: CommandOk
|
|
result: null
|
|
|]
|
|
|
|
expectedEventPayload =
|
|
[yaml|
|
|
old: null
|
|
new:
|
|
name: john
|
|
id: 3
|
|
|]
|
|
|
|
-- Insert a row into the table with event trigger
|
|
shouldReturnYaml
|
|
opts
|
|
(GraphqlEngine.postV2Query 200 testEnvironment insertQuery)
|
|
expectedResponse
|
|
|
|
-- Check if there was a payload generated due to the insert statement
|
|
eventPayload <-
|
|
-- wait for the event for a maximum of 5 seconds
|
|
timeout (5 * 1000000) (Chan.readChan eventsQueue)
|
|
>>= (`onNothing` (assertFailure "Event expected, but not fired"))
|
|
|
|
eventPayload `shouldBeYaml` expectedEventPayload
|
|
|
|
-- TODO: Update the test suite to have a seperate metadata database and source
|
|
-- database.
|
|
--
|
|
-- The following test will not work, because currently the hspec test suite
|
|
-- has no seperate metadata DB. This means by the time this test is run, the
|
|
-- pgcrypto extension is already used to make the gen_hasura_uuid function.
|
|
-- Dropping the extension also will not work, because the 'pgcrypto' extension
|
|
-- is only created on fresh database (i.e a database with no hdb_catalog schema).
|
|
--
|
|
-- Once the test suite has a seperate metadata DB, then we can do the following:
|
|
-- 1. Drop 'pgcrypto' extension if exists
|
|
-- 2. Drop 'hdb_catalog' which will only remove event trigger related stuff
|
|
-- i.e the hdb_catalog from source db (Which will make the server consider
|
|
-- it as fresh DB without any schema present)
|
|
-- 3. create a new schema for extensions
|
|
-- 4. Use the schema in the extensions_schema setting of `pg_add_source`
|
|
-- 5. This will create the pgcrypto extension the new schema
|
|
--
|
|
-- it "check: pgcrypto is installed in correct extension_schema" $
|
|
-- \(testEnvironment, _) -> do
|
|
-- let insertQuery =
|
|
-- [yaml|
|
|
-- type: run_sql
|
|
-- args:
|
|
-- source: hge_test
|
|
-- sql: |
|
|
-- SELECT e.extname AS "Name",n.nspname AS "Schema"
|
|
-- FROM pg_catalog.pg_extension e
|
|
-- LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
|
|
-- LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
|
|
-- WHERE e.extname = 'pgcrypto';
|
|
-- |]
|
|
|
|
-- expectedResponse =
|
|
-- [yaml|
|
|
-- result_type: TuplesOk
|
|
-- result:
|
|
-- - - Name
|
|
-- - Schema
|
|
-- - - pgcrypto
|
|
-- - hge_extension_schema
|
|
-- |]
|
|
|
|
-- -- Insert a row into the table with event trigger
|
|
-- shouldReturnYaml
|
|
-- opts
|
|
-- (GraphqlEngine.postV2Query 200 testEnvironment insertQuery)
|
|
-- expectedResponse
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- ** Setup and teardown override
|
|
|
|
postgresSetup :: (TestEnvironment, (GraphqlEngine.Server, Webhook.EventsQueue)) -> IO ()
|
|
postgresSetup (testEnvironment, (webhookServer, _)) = do
|
|
let sourceName = "hge_test"
|
|
extensionsSchema = "hasura" :: Text
|
|
sourceConfig =
|
|
[yaml|
|
|
connection_info:
|
|
database_url: *postgresqlConnectionString
|
|
pool_settings: {}
|
|
extensions_schema: *extensionsSchema
|
|
|]
|
|
webhookServerEchoEndpoint = GraphqlEngine.serverUrl webhookServer ++ "/echo"
|
|
|
|
GraphqlEngine.postMetadata_ testEnvironment $
|
|
[yaml|
|
|
type: pg_add_source
|
|
args:
|
|
name: *sourceName
|
|
configuration: *sourceConfig
|
|
|]
|
|
|
|
-- setup tables
|
|
Postgres.createTable testEnvironment (authorsTable "authors")
|
|
Postgres.insertTable (authorsTable "authors")
|
|
Schema.trackTable Fixture.Postgres sourceName (authorsTable "authors") testEnvironment
|
|
|
|
-- create the event trigger
|
|
GraphqlEngine.postMetadata_ testEnvironment $
|
|
[yaml|
|
|
type: bulk
|
|
args:
|
|
- type: pg_create_event_trigger
|
|
args:
|
|
name: authors_all
|
|
source: *sourceName
|
|
table:
|
|
name: authors
|
|
schema: hasura
|
|
webhook: *webhookServerEchoEndpoint
|
|
insert:
|
|
columns: "*"
|
|
|]
|
|
|
|
postgresTeardown :: (TestEnvironment, (GraphqlEngine.Server, Webhook.EventsQueue)) -> IO ()
|
|
postgresTeardown (testEnvironment, (server, _)) = do
|
|
GraphqlEngine.postMetadata_ testEnvironment $
|
|
[yaml|
|
|
type: bulk
|
|
args:
|
|
- type: pg_delete_event_trigger
|
|
args:
|
|
name: authors_all
|
|
source: hge_test
|
|
|]
|
|
stopServer server
|
|
Postgres.dropTable (authorsTable "authors")
|
|
|
|
GraphqlEngine.postMetadata_ testEnvironment $
|
|
[yaml|
|
|
type: bulk
|
|
args:
|
|
- type: pg_drop_source
|
|
args:
|
|
name: hge_test
|
|
cascade: true
|
|
|]
|
|
|
|
webhookServerMkLocalTestEnvironment ::
|
|
TestEnvironment -> IO (GraphqlEngine.Server, Webhook.EventsQueue)
|
|
webhookServerMkLocalTestEnvironment _ = do
|
|
Webhook.run
|