diff --git a/server/graphql-engine.cabal b/server/graphql-engine.cabal index 1a4cb4e21e3..6f62962cdf5 100644 --- a/server/graphql-engine.cabal +++ b/server/graphql-engine.cabal @@ -1237,7 +1237,6 @@ test-suite tests-hspec Test.BigQuery.ComputedFieldSpec Test.BigQuery.Metadata.ComputedFieldSpec Test.BigQuery.TypeInterpretationSpec - Test.ColumnPresetsSpec Test.CustomFieldNamesSpec Test.CustomRootFieldsSpec Test.DataConnector.MockAgent.AggregateQuerySpec @@ -1293,6 +1292,7 @@ test-suite tests-hspec Test.Schema.TableRelationships.ArrayRelationshipsSpec Test.Schema.TableRelationships.ObjectRelationshipsSpec Test.Schema.DataValidation.PermissionSpec + Test.Schema.DefaultValuesSpec Test.SQLServer.InsertVarcharColumnSpec Test.ServiceLivenessSpec Test.ViewsSpec diff --git a/server/tests-hspec/Test/ColumnPresetsSpec.hs b/server/tests-hspec/Test/ColumnPresetsSpec.hs deleted file mode 100644 index 3388eec53be..00000000000 --- a/server/tests-hspec/Test/ColumnPresetsSpec.hs +++ /dev/null @@ -1,282 +0,0 @@ -{-# LANGUAGE QuasiQuotes #-} - --- | Testing column presets. --- See the main hasura documentation for more information. --- --- - Postgres: https://hasura.io/docs/latest/graphql/core/databases/postgres/schema/default-values/column-presets.html --- - MSSQL: https://hasura.io/docs/latest/graphql/core/databases/ms-sql-server/schema/default-values/mssql-column-presets.html -module Test.ColumnPresetsSpec (spec) where - -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.Yaml (shouldReturnYaml, yaml) -import Harness.Test.Context qualified as Context -import Harness.Test.Schema (Table (..), table) -import Harness.Test.Schema qualified as Schema -import Harness.TestEnvironment (TestEnvironment) -import Test.Hspec (SpecWith, it) -import Prelude - --------------------------------------------------------------------------------- - --- * Preamble - -spec :: SpecWith TestEnvironment -spec = - Context.run - [ Context.Context - { name = Context.Backend Context.SQLServer, - mkLocalTestEnvironment = Context.noLocalTestEnvironment, - setup = sqlserverSetup, - teardown = Sqlserver.teardown schema, - customOptions = Nothing - }, - Context.Context - { name = Context.Backend Context.Postgres, - mkLocalTestEnvironment = Context.noLocalTestEnvironment, - setup = postgresSetup, - teardown = Postgres.teardown schema, - customOptions = Nothing - } - ] - tests - --------------------------------------------------------------------------------- - --- * Tests - -tests :: Context.Options -> SpecWith TestEnvironment -tests opts = do - ---------------------------------------- - it "admin role is unaffected by column presets" $ \testEnvironment -> - shouldReturnYaml - opts - ( GraphqlEngine.postGraphql - testEnvironment - [graphql| -mutation author { - insert_hasura_author(objects: - { name: "Author 1" - uuid: "36a6257b-1111-1111-2222-c1b7a7997087" - company: "arusah" - }) { - returning { - uuid - name - company - } - } -} -|] - ) - [yaml| -data: - insert_hasura_author: - returning: - - uuid: '36a6257b-1111-1111-2222-c1b7a7997087' - name: 'Author 1' - company: 'arusah' -|] - - ---------------------------------------- - it "applies the column presets to the 'author id' and 'company' columns" $ \testEnvironment -> - shouldReturnYaml - opts - ( GraphqlEngine.postGraphqlWithHeaders - testEnvironment - [ ("X-Hasura-Role", "user"), - ("X-Hasura-User-Id", "36a6257b-1111-1111-1111-c1b7a7997087") - ] - [graphql| -mutation author { - insert_hasura_author(objects: { name: "Author 2" }) { - returning { - uuid - name - company - } - } -} -|] - ) - [yaml| -data: - insert_hasura_author: - returning: - - uuid: '36a6257b-1111-1111-1111-c1b7a7997087' - name: 'Author 2' - company: 'hasura' -|] - - ---------------------------------------- - it "Columns with session variables presets defined are not part of the schema" $ \testEnvironment -> - shouldReturnYaml - opts - ( GraphqlEngine.postGraphqlWithHeaders - testEnvironment - [ ("X-Hasura-Role", "user"), - ("X-Hasura-User-Id", "36a6257b-1111-1111-1111-c1b7a7997087") - ] - [graphql| -mutation author { - insert_hasura_author(objects: - { name: "Author 3" - uuid: "36a6257b-1111-1111-2222-c1b7a7997087" - }) { - returning { - uuid - name - company - } - } -} -|] - ) - [yaml| -errors: -- extensions: - path: $.selectionSet.insert_hasura_author.args.objects[0].uuid - code: validation-failed - message: |- - field 'uuid' not found in type: 'hasura_author_insert_input' -|] - - ---------------------------------------- - it "Columns with static presets defined are not part of the schema" $ \testEnvironment -> - shouldReturnYaml - opts - ( GraphqlEngine.postGraphqlWithHeaders - testEnvironment - [ ("X-Hasura-Role", "user"), - ("X-Hasura-User-Id", "36a6257b-1111-1111-1111-c1b7a7997087") - ] - [graphql| -mutation author { - insert_hasura_author(objects: { name: "Author 4" company: "arusah" }) { - returning { - uuid - name - company - } - } -} -|] - ) - [yaml| -errors: -- extensions: - path: $.selectionSet.insert_hasura_author.args.objects[0].company - code: validation-failed - message: |- - field 'company' not found in type: 'hasura_author_insert_input' -|] - --------------------------------------------------------------------------------- - --- * Backend - --- ** Schema - -schema :: [Schema.Table] -schema = - [ (table "author") - { tableColumns = - [ Schema.column "uuid" Schema.TStr, - Schema.column "name" Schema.TStr, - Schema.column "company" Schema.TStr - ], - tablePrimaryKey = ["uuid"], - tableReferences = [], - tableData = [] - } - ] - --------------------------------------------------------------------------------- - --- ** Postgres backend - -postgresSetup :: (TestEnvironment, ()) -> IO () -postgresSetup (testEnvironment, localTestEnvironment) = do - Postgres.setup schema (testEnvironment, localTestEnvironment) - postgresCreatePermissions testEnvironment - -postgresCreatePermissions :: TestEnvironment -> IO () -postgresCreatePermissions testEnvironment = do - GraphqlEngine.postMetadata_ - testEnvironment - [yaml| -type: pg_create_select_permission -args: - source: postgres - table: - schema: hasura - name: author - role: user - permission: - filter: - uuid: X-Hasura-User-Id - columns: '*' -|] - GraphqlEngine.postMetadata_ - testEnvironment - [yaml| -type: pg_create_insert_permission -args: - source: postgres - table: - schema: hasura - name: author - role: user - permission: - check: {} - set: - uuid: X-Hasura-User-Id - company: hasura - columns: '*' -|] - --------------------------------------------------------------------------------- - --- ** SQL Server backend - -sqlserverSetup :: (TestEnvironment, ()) -> IO () -sqlserverSetup (testEnvironment, localTestEnvironment) = do - Sqlserver.setup schema (testEnvironment, localTestEnvironment) - sqlserverCreatePermissions testEnvironment - -sqlserverCreatePermissions :: TestEnvironment -> IO () -sqlserverCreatePermissions testEnvironment = do - GraphqlEngine.postMetadata_ - testEnvironment - [yaml| -type: mssql_create_select_permission -args: - source: mssql - table: - schema: hasura - name: author - role: user - permission: - filter: - uuid: X-Hasura-User-Id - columns: '*' -|] - GraphqlEngine.postMetadata_ - testEnvironment - [yaml| -type: mssql_create_insert_permission -args: - source: mssql - table: - schema: hasura - name: author - role: user - permission: - check: {} - set: - uuid: X-Hasura-User-Id - company: hasura - columns: '*' -|] diff --git a/server/tests-hspec/Test/Schema/DefaultValuesSpec.hs b/server/tests-hspec/Test/Schema/DefaultValuesSpec.hs new file mode 100644 index 00000000000..e6825a0b112 --- /dev/null +++ b/server/tests-hspec/Test/Schema/DefaultValuesSpec.hs @@ -0,0 +1,249 @@ +{-# LANGUAGE QuasiQuotes #-} + +-- | +-- Tests for the behaviour of columns with default values. +-- +-- https://hasura.io/docs/latest/schema/postgres/default-values/postgres-defaults/ +-- https://hasura.io/docs/latest/schema/ms-sql-server/default-values/index/ +module Test.Schema.DefaultValuesSpec (spec) where + +import Data.Aeson (Value) +import Data.Text (Text) +import Harness.Backend.Postgres qualified as Postgres +import Harness.Backend.Sqlserver qualified as Sqlserver +import Harness.GraphqlEngine (postGraphql, postGraphqlWithHeaders, postMetadata_) +import Harness.Quoter.Graphql (graphql) +import Harness.Quoter.Yaml (shouldReturnYaml, yaml) +import Harness.Test.Context (Options (..)) +import Harness.Test.Context qualified as Context +import Harness.Test.Schema (Table (..), table) +import Harness.Test.Schema qualified as Schema +import Harness.TestEnvironment (TestEnvironment) +import Test.Hspec (SpecWith, describe, it) +import Prelude + +spec :: SpecWith TestEnvironment +spec = + Context.run + [ Context.Context + { name = Context.Backend Context.Postgres, + mkLocalTestEnvironment = Context.noLocalTestEnvironment, + setup = Postgres.setup schema <> setupMetadata "postgres", + teardown = Postgres.teardown schema, + customOptions = Nothing + }, + Context.Context + { name = Context.Backend Context.SQLServer, + mkLocalTestEnvironment = Context.noLocalTestEnvironment, + setup = Sqlserver.setup schema <> setupMetadata "mssql", + teardown = Sqlserver.teardown schema, + customOptions = Nothing + } + ] + tests + +-------------------------------------------------------------------------------- +-- Schema + +schema :: [Schema.Table] +schema = + [ (table "author") + { tableColumns = + [ Schema.column "uuid" Schema.TStr, + Schema.column "name" Schema.TStr, + Schema.column "company" Schema.TStr + ], + tablePrimaryKey = ["uuid"], + tableData = [] + } + ] + +-------------------------------------------------------------------------------- +-- Tests + +tests :: Options -> SpecWith TestEnvironment +tests opts = do + let shouldBe :: IO Value -> Value -> IO () + shouldBe = shouldReturnYaml opts + + describe "Default values for inserts" do + it "Uses default values" \testEnvironment -> do + let expected :: Value + expected = + [yaml| + data: + insert_hasura_author: + returning: + - uuid: "36a6257b-1111-1111-1111-c1b7a7997087" + name: "Author 1" + company: "hasura" + |] + + actual :: IO Value + actual = + postGraphqlWithHeaders + testEnvironment + [ ("X-Hasura-Role", "user"), + ("X-Hasura-User-Id", "36a6257b-1111-1111-1111-c1b7a7997087") + ] + [graphql| + mutation author { + insert_hasura_author(objects: { name: "Author 1" }) { + returning { + uuid + name + company + } + } + } + |] + + actual `shouldBe` expected + + it "Hides columns with defaults from the schema" \testEnvironment -> do + let expected :: Value + expected = + [yaml| + errors: + - extensions: + path: $.selectionSet.insert_hasura_author.args.objects[0].company + code: validation-failed + message: |- + field 'company' not found in type: 'hasura_author_insert_input' + |] + + actual :: IO Value + actual = + postGraphqlWithHeaders + testEnvironment + [ ("X-Hasura-Role", "user"), + ("X-Hasura-User-Id", "36a6257b-1111-1111-1111-c1b7a7997087") + ] + [graphql| + mutation author { + insert_hasura_author(objects: { + name: "Author 2", + company: "arusah" + }) { + returning { + uuid + name + company + } + } + } + |] + + actual `shouldBe` expected + + it "Hides columns with session-given defaults from the schema" \testEnvironment -> do + let expected :: Value + expected = + [yaml| + errors: + - extensions: + path: $.selectionSet.insert_hasura_author.args.objects[0].uuid + code: validation-failed + message: |- + field 'uuid' not found in type: 'hasura_author_insert_input' + |] + + actual :: IO Value + actual = + postGraphqlWithHeaders + testEnvironment + [ ("X-Hasura-Role", "user"), + ("X-Hasura-User-Id", "36a6257b-1111-1111-1111-c1b7a7997087") + ] + [graphql| + mutation author { + insert_hasura_author(objects: { + name: "Author 3", + uuid: "36a6257b-1111-1111-2222-c1b7a7997087" + }) { + returning { + uuid + name + company + } + } + } + |] + + actual `shouldBe` expected + + it "Allows admin roles to insert into columns with defaults" \testEnvironment -> do + let expected :: Value + expected = + [yaml| + data: + insert_hasura_author: + returning: + - uuid: "36a6257b-1111-1111-2222-c1b7a7997087" + name: "Author 4" + company: "Not Hasura" + |] + + actual :: IO Value + actual = + postGraphql + testEnvironment + [graphql| + mutation author { + insert_hasura_author(objects: + { name: "Author 4" + uuid: "36a6257b-1111-1111-2222-c1b7a7997087" + company: "Not Hasura" + }) { + returning { + uuid + name + company + } + } + } + |] + + actual `shouldBe` expected + +-------------------------------------------------------------------------------- +-- Metadata + +setupMetadata :: Text -> (TestEnvironment, ()) -> IO () +setupMetadata backend (testEnvironment, _) = do + let select = backend <> "_create_select_permission" + insert = backend <> "_create_insert_permission" + + postMetadata_ + testEnvironment + [yaml| + type: *select + args: + source: *backend + table: + schema: hasura + name: author + role: user + permission: + filter: + uuid: X-Hasura-User-Id + columns: '*' + |] + + postMetadata_ + testEnvironment + [yaml| + type: *insert + args: + source: *backend + table: + schema: hasura + name: author + role: user + permission: + check: {} + set: + uuid: X-Hasura-User-Id + company: hasura + columns: '*' + |]