mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-09-11 10:46:25 +03:00
Refactor Mock Data Connector Agent Integration Tests
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7531 GitOrigin-RevId: b5111a46ba42c22b110a021b8d0404b114edaba7
This commit is contained in:
parent
8d6b9f70f1
commit
308d310d62
@ -7,17 +7,18 @@ module Test.DataConnector.MockAgent.AggregateQuerySpec (spec) where
|
||||
import Data.Aeson qualified as Aeson
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Data.List.NonEmpty qualified as NE
|
||||
import Harness.Backend.DataConnector.Mock (TestCase (..))
|
||||
import Harness.Backend.DataConnector.Mock (AgentRequest (..), MockRequestResults (..), mockAgentTest, mockQueryResponse)
|
||||
import Harness.Backend.DataConnector.Mock qualified as Mock
|
||||
import Harness.Quoter.Graphql (graphql)
|
||||
import Harness.Quoter.Yaml (yaml)
|
||||
import Harness.Test.BackendType qualified as BackendType
|
||||
import Harness.Test.Fixture qualified as Fixture
|
||||
import Harness.TestEnvironment (GlobalTestEnvironment, TestEnvironment)
|
||||
import Harness.Yaml (shouldBeYaml)
|
||||
import Hasura.Backends.DataConnector.API qualified as API
|
||||
import Hasura.Prelude
|
||||
import Language.GraphQL.Draft.Syntax.QQ qualified as G
|
||||
import Test.Hspec (SpecWith, describe, it)
|
||||
import Test.Hspec (SpecWith, describe, shouldBe)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -83,250 +84,249 @@ sourceMetadata =
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
tests :: Fixture.Options -> SpecWith (TestEnvironment, Mock.MockAgentEnvironment)
|
||||
tests opts = describe "Aggregate Query Tests" $ do
|
||||
it "works with multiple nodes fields and through array relations" $
|
||||
Mock.runTest opts $
|
||||
let required =
|
||||
Mock.TestCaseRequired
|
||||
{ _givenRequired =
|
||||
let response =
|
||||
[ [ (API.FieldName "ArtistIds_Id", API.mkColumnFieldValue $ Aeson.Number 1),
|
||||
(API.FieldName "ArtistNames_Name", API.mkColumnFieldValue $ Aeson.String "AC/DC"),
|
||||
( API.FieldName "nodes_Albums",
|
||||
API.mkRelationshipFieldValue $
|
||||
rowsResponse
|
||||
[ [(API.FieldName "nodes_Title", API.mkColumnFieldValue $ Aeson.String "For Those About To Rock We Salute You")],
|
||||
[(API.FieldName "nodes_Title", API.mkColumnFieldValue $ Aeson.String "Let There Be Rock")]
|
||||
]
|
||||
)
|
||||
]
|
||||
]
|
||||
in Mock.chinookMock {Mock._queryResponse = \_ -> Right (rowsResponse response)},
|
||||
_whenRequestRequired =
|
||||
[graphql|
|
||||
query getArtist {
|
||||
Artist_aggregate(limit: 1) {
|
||||
ArtistIds: nodes {
|
||||
Id: ArtistId
|
||||
}
|
||||
ArtistNames: nodes {
|
||||
Name
|
||||
}
|
||||
nodes {
|
||||
Albums: Albums_aggregate {
|
||||
nodes {
|
||||
Title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tests _opts = describe "Aggregate Query Tests" $ do
|
||||
mockAgentTest "works with multiple nodes fields and through array relations" $ \performGraphqlRequest -> do
|
||||
let headers = []
|
||||
let graphqlRequest =
|
||||
[graphql|
|
||||
query getArtist {
|
||||
Artist_aggregate(limit: 1) {
|
||||
ArtistIds: nodes {
|
||||
Id: ArtistId
|
||||
}
|
||||
ArtistNames: nodes {
|
||||
Name
|
||||
}
|
||||
nodes {
|
||||
Albums: Albums_aggregate {
|
||||
nodes {
|
||||
Title
|
||||
}
|
||||
|],
|
||||
_thenRequired =
|
||||
[yaml|
|
||||
data:
|
||||
Artist_aggregate:
|
||||
ArtistIds:
|
||||
- Id: 1
|
||||
ArtistNames:
|
||||
- Name: AC/DC
|
||||
nodes:
|
||||
- Albums:
|
||||
nodes:
|
||||
- Title: For Those About To Rock We Salute You
|
||||
- Title: Let There Be Rock
|
||||
|]
|
||||
}
|
||||
}
|
||||
}
|
||||
in (Mock.defaultTestCase required)
|
||||
{ _whenQuery =
|
||||
Just
|
||||
( API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Artist" :| []),
|
||||
_qrTableRelationships =
|
||||
[ API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Artist" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "Albums",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Album" :| []),
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "ArtistIds_Id", API.ColumnField (API.ColumnName "ArtistId") (API.ScalarType "number")),
|
||||
(API.FieldName "ArtistNames_Name", API.ColumnField (API.ColumnName "Name") (API.ScalarType "string")),
|
||||
( API.FieldName "nodes_Albums",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "Albums")
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "nodes_Title", API.ColumnField (API.ColumnName "Title") (API.ScalarType "string"))
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
)
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|]
|
||||
let queryResponse =
|
||||
rowsResponse
|
||||
[ [ (API.FieldName "ArtistIds_Id", API.mkColumnFieldValue $ Aeson.Number 1),
|
||||
(API.FieldName "ArtistNames_Name", API.mkColumnFieldValue $ Aeson.String "AC/DC"),
|
||||
( API.FieldName "nodes_Albums",
|
||||
API.mkRelationshipFieldValue $
|
||||
rowsResponse
|
||||
[ [(API.FieldName "nodes_Title", API.mkColumnFieldValue $ Aeson.String "For Those About To Rock We Salute You")],
|
||||
[(API.FieldName "nodes_Title", API.mkColumnFieldValue $ Aeson.String "Let There Be Rock")]
|
||||
]
|
||||
)
|
||||
]
|
||||
]
|
||||
let mockConfig = Mock.chinookMock & mockQueryResponse queryResponse
|
||||
|
||||
it "works with multiple aggregate fields and through array relations" $
|
||||
Mock.runTest opts $
|
||||
let required =
|
||||
Mock.TestCaseRequired
|
||||
{ _givenRequired =
|
||||
let aggregates =
|
||||
[ (API.FieldName "counts_count", Aeson.Number 2),
|
||||
(API.FieldName "counts_uniqueBillingCountries", Aeson.Number 2),
|
||||
(API.FieldName "ids_minimum_Id", Aeson.Number 1),
|
||||
(API.FieldName "ids_max_InvoiceId", Aeson.Number 2)
|
||||
]
|
||||
rows =
|
||||
[ [ ( API.FieldName "nodes_Lines",
|
||||
API.mkRelationshipFieldValue $
|
||||
aggregatesResponse
|
||||
[ (API.FieldName "aggregate_count", Aeson.Number 2)
|
||||
]
|
||||
)
|
||||
],
|
||||
[ ( API.FieldName "nodes_Lines",
|
||||
API.mkRelationshipFieldValue $
|
||||
aggregatesResponse
|
||||
[ (API.FieldName "aggregate_count", Aeson.Number 4)
|
||||
]
|
||||
)
|
||||
]
|
||||
]
|
||||
in Mock.chinookMock {Mock._queryResponse = \_ -> Right (aggregatesAndRowsResponse aggregates rows)},
|
||||
_whenRequestRequired =
|
||||
[graphql|
|
||||
query getInvoices {
|
||||
Invoice_aggregate(limit: 2) {
|
||||
counts: aggregate {
|
||||
count
|
||||
uniqueBillingCountries: count(column: BillingCountry, distinct: true)
|
||||
}
|
||||
ids: aggregate {
|
||||
minimum: min {
|
||||
Id: InvoiceId
|
||||
}
|
||||
max {
|
||||
InvoiceId
|
||||
}
|
||||
}
|
||||
nodes {
|
||||
Lines: InvoiceLines_aggregate {
|
||||
aggregate {
|
||||
count
|
||||
}
|
||||
}
|
||||
}
|
||||
MockRequestResults {..} <- performGraphqlRequest mockConfig headers graphqlRequest
|
||||
|
||||
_mrrGraphqlResponse
|
||||
`shouldBeYaml` [yaml|
|
||||
data:
|
||||
Artist_aggregate:
|
||||
ArtistIds:
|
||||
- Id: 1
|
||||
ArtistNames:
|
||||
- Name: AC/DC
|
||||
nodes:
|
||||
- Albums:
|
||||
nodes:
|
||||
- Title: For Those About To Rock We Salute You
|
||||
- Title: Let There Be Rock
|
||||
|]
|
||||
|
||||
_mrrRecordedRequest
|
||||
`shouldBe` Just
|
||||
( Query $
|
||||
API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Artist" :| []),
|
||||
_qrTableRelationships =
|
||||
[ API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Artist" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "Albums",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Album" :| []),
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "ArtistIds_Id", API.ColumnField (API.ColumnName "ArtistId") (API.ScalarType "number")),
|
||||
(API.FieldName "ArtistNames_Name", API.ColumnField (API.ColumnName "Name") (API.ScalarType "string")),
|
||||
( API.FieldName "nodes_Albums",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "Albums")
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "nodes_Title", API.ColumnField (API.ColumnName "Title") (API.ScalarType "string"))
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
)
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
|],
|
||||
_thenRequired =
|
||||
[yaml|
|
||||
data:
|
||||
Invoice_aggregate:
|
||||
counts:
|
||||
count: 2
|
||||
uniqueBillingCountries: 2
|
||||
ids:
|
||||
minimum:
|
||||
Id: 1
|
||||
max:
|
||||
InvoiceId: 2
|
||||
nodes:
|
||||
- Lines:
|
||||
aggregate:
|
||||
count: 2
|
||||
- Lines:
|
||||
aggregate:
|
||||
count: 4
|
||||
|]
|
||||
}
|
||||
in (Mock.defaultTestCase required)
|
||||
{ _whenQuery =
|
||||
Just
|
||||
( API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Invoice" :| []),
|
||||
_qrTableRelationships =
|
||||
[ API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Invoice" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "InvoiceLines",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("InvoiceLine" :| []),
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "InvoiceId", API.ColumnName "InvoiceId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ ( API.FieldName "nodes_Lines",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "InvoiceLines")
|
||||
API.Query
|
||||
{ _qFields = Nothing,
|
||||
_qAggregates =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[(API.FieldName "aggregate_count", API.StarCount)],
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
)
|
||||
],
|
||||
_qAggregates =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "counts_count", API.StarCount),
|
||||
(API.FieldName "counts_uniqueBillingCountries", API.ColumnCount (API.ColumnCountAggregate (API.ColumnName "BillingCountry") True)),
|
||||
(API.FieldName "ids_minimum_Id", API.SingleColumn (singleColumnAggregateMin (API.ColumnName "InvoiceId"))),
|
||||
(API.FieldName "ids_max_InvoiceId", API.SingleColumn (singleColumnAggregateMax (API.ColumnName "InvoiceId")))
|
||||
],
|
||||
_qLimit = Just 2,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
mockAgentTest "works with multiple aggregate fields and through array relations" $ \performGraphqlRequest -> do
|
||||
let headers = []
|
||||
let graphqlRequest =
|
||||
[graphql|
|
||||
query getInvoices {
|
||||
Invoice_aggregate(limit: 2) {
|
||||
counts: aggregate {
|
||||
count
|
||||
uniqueBillingCountries: count(column: BillingCountry, distinct: true)
|
||||
}
|
||||
ids: aggregate {
|
||||
minimum: min {
|
||||
Id: InvoiceId
|
||||
}
|
||||
max {
|
||||
InvoiceId
|
||||
}
|
||||
}
|
||||
nodes {
|
||||
Lines: InvoiceLines_aggregate {
|
||||
aggregate {
|
||||
count
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|]
|
||||
let aggregates =
|
||||
[ (API.FieldName "counts_count", Aeson.Number 2),
|
||||
(API.FieldName "counts_uniqueBillingCountries", Aeson.Number 2),
|
||||
(API.FieldName "ids_minimum_Id", Aeson.Number 1),
|
||||
(API.FieldName "ids_max_InvoiceId", Aeson.Number 2)
|
||||
]
|
||||
rows =
|
||||
[ [ ( API.FieldName "nodes_Lines",
|
||||
API.mkRelationshipFieldValue $
|
||||
aggregatesResponse
|
||||
[ (API.FieldName "aggregate_count", Aeson.Number 2)
|
||||
]
|
||||
)
|
||||
],
|
||||
[ ( API.FieldName "nodes_Lines",
|
||||
API.mkRelationshipFieldValue $
|
||||
aggregatesResponse
|
||||
[ (API.FieldName "aggregate_count", Aeson.Number 4)
|
||||
]
|
||||
)
|
||||
]
|
||||
]
|
||||
let mockConfig = Mock.chinookMock & mockQueryResponse (aggregatesAndRowsResponse aggregates rows)
|
||||
|
||||
MockRequestResults {..} <- performGraphqlRequest mockConfig headers graphqlRequest
|
||||
|
||||
_mrrGraphqlResponse
|
||||
`shouldBeYaml` [yaml|
|
||||
data:
|
||||
Invoice_aggregate:
|
||||
counts:
|
||||
count: 2
|
||||
uniqueBillingCountries: 2
|
||||
ids:
|
||||
minimum:
|
||||
Id: 1
|
||||
max:
|
||||
InvoiceId: 2
|
||||
nodes:
|
||||
- Lines:
|
||||
aggregate:
|
||||
count: 2
|
||||
- Lines:
|
||||
aggregate:
|
||||
count: 4
|
||||
|]
|
||||
|
||||
_mrrRecordedRequest
|
||||
`shouldBe` Just
|
||||
( Query $
|
||||
API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Invoice" :| []),
|
||||
_qrTableRelationships =
|
||||
[ API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Invoice" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "InvoiceLines",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("InvoiceLine" :| []),
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "InvoiceId", API.ColumnName "InvoiceId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ ( API.FieldName "nodes_Lines",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "InvoiceLines")
|
||||
API.Query
|
||||
{ _qFields = Nothing,
|
||||
_qAggregates =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[(API.FieldName "aggregate_count", API.StarCount)],
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
)
|
||||
],
|
||||
_qAggregates =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "counts_count", API.StarCount),
|
||||
(API.FieldName "counts_uniqueBillingCountries", API.ColumnCount (API.ColumnCountAggregate (API.ColumnName "BillingCountry") True)),
|
||||
(API.FieldName "ids_minimum_Id", API.SingleColumn (singleColumnAggregateMin (API.ColumnName "InvoiceId"))),
|
||||
(API.FieldName "ids_max_InvoiceId", API.SingleColumn (singleColumnAggregateMax (API.ColumnName "InvoiceId")))
|
||||
],
|
||||
_qLimit = Just 2,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
rowsResponse :: [[(API.FieldName, API.FieldValue)]] -> API.QueryResponse
|
||||
rowsResponse rows = API.QueryResponse (Just $ HashMap.fromList <$> rows) Nothing
|
||||
|
@ -10,16 +10,17 @@ import Data.Aeson qualified as Aeson
|
||||
import Data.ByteString (ByteString)
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Data.List.NonEmpty qualified as NE
|
||||
import Harness.Backend.DataConnector.Mock (TestCase (..))
|
||||
import Harness.Backend.DataConnector.Mock (AgentRequest (..), MockRequestResults (..), mockAgentTest, mockQueryResponse)
|
||||
import Harness.Backend.DataConnector.Mock qualified as Mock
|
||||
import Harness.Quoter.Graphql (graphql)
|
||||
import Harness.Quoter.Yaml (yaml)
|
||||
import Harness.Test.BackendType qualified as BackendType
|
||||
import Harness.Test.Fixture qualified as Fixture
|
||||
import Harness.TestEnvironment (GlobalTestEnvironment, TestEnvironment)
|
||||
import Harness.Yaml (shouldBeYaml)
|
||||
import Hasura.Backends.DataConnector.API qualified as API
|
||||
import Hasura.Prelude
|
||||
import Test.Hspec (SpecWith, describe, it)
|
||||
import Test.Hspec (SpecWith, describe, shouldBe)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -104,185 +105,183 @@ sourceMetadata =
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
tests :: Fixture.Options -> SpecWith (TestEnvironment, Mock.MockAgentEnvironment)
|
||||
tests opts = do
|
||||
describe "Basic Tests" $ do
|
||||
it "works with simple object query" $
|
||||
Mock.runTest opts $
|
||||
let required =
|
||||
Mock.TestCaseRequired
|
||||
{ _givenRequired =
|
||||
let albums =
|
||||
[ [ (API.FieldName "id", API.mkColumnFieldValue $ Aeson.Number 1),
|
||||
(API.FieldName "title", API.mkColumnFieldValue $ Aeson.String "For Those About To Rock We Salute You")
|
||||
]
|
||||
]
|
||||
in Mock.chinookMock {Mock._queryResponse = \_ -> Right (rowsResponse albums)},
|
||||
_whenRequestRequired =
|
||||
[graphql|
|
||||
query getAlbum {
|
||||
albums(limit: 1) {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
|],
|
||||
_thenRequired =
|
||||
[yaml|
|
||||
data:
|
||||
albums:
|
||||
- id: 1
|
||||
title: For Those About To Rock We Salute You
|
||||
|]
|
||||
}
|
||||
in (Mock.defaultTestCase required)
|
||||
{ _whenQuery =
|
||||
Just
|
||||
( API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Album" :| []),
|
||||
_qrTableRelationships = [],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") (API.ScalarType "number")),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") (API.ScalarType "string"))
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
tests _opts = describe "Basic Tests" $ do
|
||||
mockAgentTest "works with simple object query" $ \performGraphqlRequest -> do
|
||||
let headers = []
|
||||
let graphqlRequest =
|
||||
[graphql|
|
||||
query getAlbum {
|
||||
albums(limit: 1) {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
|]
|
||||
let queryResponse =
|
||||
rowsResponse
|
||||
[ [ (API.FieldName "id", API.mkColumnFieldValue $ Aeson.Number 1),
|
||||
(API.FieldName "title", API.mkColumnFieldValue $ Aeson.String "For Those About To Rock We Salute You")
|
||||
]
|
||||
]
|
||||
let mockConfig = Mock.chinookMock & mockQueryResponse queryResponse
|
||||
|
||||
it "works with order_by id" $
|
||||
Mock.runTest opts $
|
||||
let required =
|
||||
Mock.TestCaseRequired
|
||||
{ _givenRequired =
|
||||
let albums =
|
||||
[ [ (API.FieldName "id", API.mkColumnFieldValue $ Aeson.Number 1),
|
||||
(API.FieldName "title", API.mkColumnFieldValue $ Aeson.String "For Those About To Rock We Salute You")
|
||||
],
|
||||
[ (API.FieldName "id", API.mkColumnFieldValue $ Aeson.Number 2),
|
||||
(API.FieldName "title", API.mkColumnFieldValue $ Aeson.String "Balls to the Wall")
|
||||
],
|
||||
[ (API.FieldName "id", API.mkColumnFieldValue $ Aeson.Number 3),
|
||||
(API.FieldName "title", API.mkColumnFieldValue $ Aeson.String "Restless and Wild")
|
||||
]
|
||||
]
|
||||
in Mock.chinookMock {Mock._queryResponse = \_ -> Right (rowsResponse albums)},
|
||||
_whenRequestRequired =
|
||||
[graphql|
|
||||
query getAlbum {
|
||||
albums(limit: 3, order_by: {id: asc}) {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
|],
|
||||
_thenRequired =
|
||||
[yaml|
|
||||
data:
|
||||
albums:
|
||||
- id: 1
|
||||
title: For Those About To Rock We Salute You
|
||||
- id: 2
|
||||
title: Balls to the Wall
|
||||
- id: 3
|
||||
title: Restless and Wild
|
||||
|]
|
||||
}
|
||||
in (Mock.defaultTestCase required)
|
||||
{ _whenQuery =
|
||||
Just
|
||||
( API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Album" :| []),
|
||||
_qrTableRelationships = [],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 3,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Just (API.OrderBy mempty (API.OrderByElement [] (API.OrderByColumn (API.ColumnName "AlbumId")) API.Ascending :| []))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
MockRequestResults {..} <- performGraphqlRequest mockConfig headers graphqlRequest
|
||||
|
||||
it "works with an exists-based permissions filter" $
|
||||
Mock.runTest opts $
|
||||
let required =
|
||||
Mock.TestCaseRequired
|
||||
{ _givenRequired =
|
||||
let albums =
|
||||
[ [ (API.FieldName "CustomerId", API.mkColumnFieldValue $ Aeson.Number 1)
|
||||
_mrrGraphqlResponse
|
||||
`shouldBeYaml` [yaml|
|
||||
data:
|
||||
albums:
|
||||
- id: 1
|
||||
title: For Those About To Rock We Salute You
|
||||
|]
|
||||
|
||||
_mrrRecordedRequest
|
||||
`shouldBe` Just
|
||||
( Query $
|
||||
API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Album" :| []),
|
||||
_qrTableRelationships = [],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") (API.ScalarType "number")),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") (API.ScalarType "string"))
|
||||
],
|
||||
[ (API.FieldName "CustomerId", API.mkColumnFieldValue $ Aeson.Number 2)
|
||||
],
|
||||
[ (API.FieldName "CustomerId", API.mkColumnFieldValue $ Aeson.Number 3)
|
||||
]
|
||||
]
|
||||
in Mock.chinookMock {Mock._queryResponse = \_ -> Right (rowsResponse albums)},
|
||||
_whenRequestRequired =
|
||||
[graphql|
|
||||
query getCustomers {
|
||||
Customer {
|
||||
CustomerId
|
||||
}
|
||||
}
|
||||
|],
|
||||
_thenRequired =
|
||||
[yaml|
|
||||
data:
|
||||
Customer:
|
||||
- CustomerId: 1
|
||||
- CustomerId: 2
|
||||
- CustomerId: 3
|
||||
|]
|
||||
}
|
||||
in (Mock.defaultTestCase required)
|
||||
{ _whenRequestHeaders =
|
||||
[ ("X-Hasura-Role", testRoleName),
|
||||
("X-Hasura-EmployeeId", "1")
|
||||
],
|
||||
_whenQuery =
|
||||
Just
|
||||
( API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Customer" :| []),
|
||||
_qrTableRelationships = [],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "CustomerId", API.ColumnField (API.ColumnName "CustomerId") $ API.ScalarType "number")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere =
|
||||
Just $
|
||||
API.Exists (API.UnrelatedTable $ API.TableName ("Employee" :| [])) $
|
||||
API.ApplyBinaryComparisonOperator
|
||||
API.Equal
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "EmployeeId") $ API.ScalarType "number")
|
||||
(API.ScalarValue (Aeson.Number 1) $ API.ScalarType "number"),
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
mockAgentTest "works with order_by id" $ \performGraphqlRequest -> do
|
||||
let headers = []
|
||||
let graphqlRequest =
|
||||
[graphql|
|
||||
query getAlbum {
|
||||
albums(limit: 3, order_by: {id: asc}) {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
|]
|
||||
let queryResponse =
|
||||
rowsResponse
|
||||
[ [ (API.FieldName "id", API.mkColumnFieldValue $ Aeson.Number 1),
|
||||
(API.FieldName "title", API.mkColumnFieldValue $ Aeson.String "For Those About To Rock We Salute You")
|
||||
],
|
||||
[ (API.FieldName "id", API.mkColumnFieldValue $ Aeson.Number 2),
|
||||
(API.FieldName "title", API.mkColumnFieldValue $ Aeson.String "Balls to the Wall")
|
||||
],
|
||||
[ (API.FieldName "id", API.mkColumnFieldValue $ Aeson.Number 3),
|
||||
(API.FieldName "title", API.mkColumnFieldValue $ Aeson.String "Restless and Wild")
|
||||
]
|
||||
]
|
||||
let mockConfig = Mock.chinookMock & mockQueryResponse queryResponse
|
||||
|
||||
MockRequestResults {..} <- performGraphqlRequest mockConfig headers graphqlRequest
|
||||
|
||||
_mrrGraphqlResponse
|
||||
`shouldBeYaml` [yaml|
|
||||
data:
|
||||
albums:
|
||||
- id: 1
|
||||
title: For Those About To Rock We Salute You
|
||||
- id: 2
|
||||
title: Balls to the Wall
|
||||
- id: 3
|
||||
title: Restless and Wild
|
||||
|]
|
||||
|
||||
_mrrRecordedRequest
|
||||
`shouldBe` Just
|
||||
( Query $
|
||||
API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Album" :| []),
|
||||
_qrTableRelationships = [],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 3,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Just (API.OrderBy mempty (API.OrderByElement [] (API.OrderByColumn (API.ColumnName "AlbumId")) API.Ascending :| []))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
mockAgentTest "works with an exists-based permissions filter" $ \performGraphqlRequest -> do
|
||||
let headers =
|
||||
[ ("X-Hasura-Role", testRoleName),
|
||||
("X-Hasura-EmployeeId", "1")
|
||||
]
|
||||
let graphqlRequest =
|
||||
[graphql|
|
||||
query getCustomers {
|
||||
Customer {
|
||||
CustomerId
|
||||
}
|
||||
}
|
||||
|]
|
||||
let queryResponse =
|
||||
rowsResponse
|
||||
[ [ (API.FieldName "CustomerId", API.mkColumnFieldValue $ Aeson.Number 1)
|
||||
],
|
||||
[ (API.FieldName "CustomerId", API.mkColumnFieldValue $ Aeson.Number 2)
|
||||
],
|
||||
[ (API.FieldName "CustomerId", API.mkColumnFieldValue $ Aeson.Number 3)
|
||||
]
|
||||
]
|
||||
let mockConfig = Mock.chinookMock & mockQueryResponse queryResponse
|
||||
|
||||
MockRequestResults {..} <- performGraphqlRequest mockConfig headers graphqlRequest
|
||||
|
||||
_mrrGraphqlResponse
|
||||
`shouldBeYaml` [yaml|
|
||||
data:
|
||||
Customer:
|
||||
- CustomerId: 1
|
||||
- CustomerId: 2
|
||||
- CustomerId: 3
|
||||
|]
|
||||
|
||||
_mrrRecordedRequest
|
||||
`shouldBe` Just
|
||||
( Query $
|
||||
API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Customer" :| []),
|
||||
_qrTableRelationships = [],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "CustomerId", API.ColumnField (API.ColumnName "CustomerId") $ API.ScalarType "number")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere =
|
||||
Just $
|
||||
API.Exists (API.UnrelatedTable $ API.TableName ("Employee" :| [])) $
|
||||
API.ApplyBinaryComparisonOperator
|
||||
API.Equal
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "EmployeeId") $ API.ScalarType "number")
|
||||
(API.ScalarValue (Aeson.Number 1) $ API.ScalarType "number"),
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
rowsResponse :: [[(API.FieldName, API.FieldValue)]] -> API.QueryResponse
|
||||
rowsResponse rows = API.QueryResponse (Just $ HashMap.fromList <$> rows) Nothing
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,16 +9,17 @@ module Test.DataConnector.MockAgent.ErrorSpec (spec) where
|
||||
import Data.Aeson qualified as Aeson
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Data.List.NonEmpty qualified as NE
|
||||
import Harness.Backend.DataConnector.Mock (TestCase (..))
|
||||
import Harness.Backend.DataConnector.Mock (AgentRequest (..), MockRequestResults (..), mockAgentTest)
|
||||
import Harness.Backend.DataConnector.Mock qualified as Mock
|
||||
import Harness.Quoter.Graphql (graphql)
|
||||
import Harness.Quoter.Yaml (yaml)
|
||||
import Harness.Test.BackendType qualified as BackendType
|
||||
import Harness.Test.Fixture qualified as Fixture
|
||||
import Harness.TestEnvironment (GlobalTestEnvironment, TestEnvironment)
|
||||
import Harness.Yaml (shouldBeYaml)
|
||||
import Hasura.Backends.DataConnector.API qualified as API
|
||||
import Hasura.Prelude
|
||||
import Test.Hspec (SpecWith, describe, it)
|
||||
import Test.Hspec (SpecWith, describe, shouldBe)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -59,55 +60,54 @@ sourceMetadata =
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
tests :: Fixture.Options -> SpecWith (TestEnvironment, Mock.MockAgentEnvironment)
|
||||
tests opts = do
|
||||
describe "Error Protocol Tests" $ do
|
||||
it "handles returned errors correctly" $
|
||||
Mock.runTest opts $
|
||||
let errorResponse = API.ErrorResponse API.UncaughtError "Hello World!" [yaml| { foo: "bar" } |]
|
||||
required =
|
||||
Mock.TestCaseRequired
|
||||
{ _givenRequired = Mock.chinookMock {Mock._queryResponse = \_ -> Left errorResponse},
|
||||
_whenRequestRequired =
|
||||
[graphql|
|
||||
query getAlbum {
|
||||
albums(limit: 1) {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
|],
|
||||
_thenRequired =
|
||||
[yaml|
|
||||
errors:
|
||||
-
|
||||
extensions:
|
||||
code: "data-connector-error"
|
||||
path: "$"
|
||||
internal:
|
||||
foo: "bar"
|
||||
message: "UncaughtError: Hello World!"
|
||||
|]
|
||||
}
|
||||
in (Mock.defaultTestCase required)
|
||||
{ _whenQuery =
|
||||
Just
|
||||
( API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Album" :| []),
|
||||
_qrTableRelationships = [],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
tests _opts = describe "Error Protocol Tests" $ do
|
||||
mockAgentTest "handles returned errors correctly" $ \performGraphqlRequest -> do
|
||||
let headers = []
|
||||
let graphqlRequest =
|
||||
[graphql|
|
||||
query getAlbum {
|
||||
albums(limit: 1) {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
|]
|
||||
let errorResponse = API.ErrorResponse API.UncaughtError "Hello World!" [yaml| { foo: "bar" } |]
|
||||
let mockConfig = Mock.chinookMock {Mock._queryResponse = \_ -> Left errorResponse}
|
||||
|
||||
MockRequestResults {..} <- performGraphqlRequest mockConfig headers graphqlRequest
|
||||
|
||||
_mrrGraphqlResponse
|
||||
`shouldBeYaml` [yaml|
|
||||
errors:
|
||||
-
|
||||
extensions:
|
||||
code: "data-connector-error"
|
||||
path: "$"
|
||||
internal:
|
||||
foo: "bar"
|
||||
message: "UncaughtError: Hello World!"
|
||||
|]
|
||||
|
||||
_mrrRecordedRequest
|
||||
`shouldBe` Just
|
||||
( Query $
|
||||
API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Album" :| []),
|
||||
_qrTableRelationships = [],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -9,16 +9,17 @@ import Data.Aeson qualified as Aeson
|
||||
import Data.ByteString (ByteString)
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Data.List.NonEmpty qualified as NE
|
||||
import Harness.Backend.DataConnector.Mock (TestCase (..))
|
||||
import Harness.Backend.DataConnector.Mock (AgentRequest (..), MockRequestResults (..), mockAgentTest, mockQueryResponse)
|
||||
import Harness.Backend.DataConnector.Mock qualified as Mock
|
||||
import Harness.Quoter.Graphql (graphql)
|
||||
import Harness.Quoter.Yaml (yaml)
|
||||
import Harness.Test.BackendType qualified as BackendType
|
||||
import Harness.Test.Fixture qualified as Fixture
|
||||
import Harness.TestEnvironment (GlobalTestEnvironment, TestEnvironment)
|
||||
import Harness.Yaml (shouldBeYaml)
|
||||
import Hasura.Backends.DataConnector.API qualified as API
|
||||
import Hasura.Prelude
|
||||
import Test.Hspec (SpecWith, describe, it)
|
||||
import Test.Hspec (SpecWith, describe, shouldBe)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -126,386 +127,384 @@ sourceMetadata =
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
tests :: Fixture.Options -> SpecWith (TestEnvironment, Mock.MockAgentEnvironment)
|
||||
tests opts = do
|
||||
describe "Object Relationships Tests" $ do
|
||||
it "works with multiple object relationships" $
|
||||
Mock.runTest opts $
|
||||
let required =
|
||||
Mock.TestCaseRequired
|
||||
{ _givenRequired =
|
||||
let albums =
|
||||
[ [ (API.FieldName "Name", API.mkColumnFieldValue $ Aeson.String "For Those About To Rock (We Salute You)"),
|
||||
( API.FieldName "Genre",
|
||||
API.mkRelationshipFieldValue $
|
||||
rowsResponse
|
||||
[ [(API.FieldName "Name", API.mkColumnFieldValue $ Aeson.String "Rock")]
|
||||
]
|
||||
tests _opts = describe "Object Relationships Tests" $ do
|
||||
mockAgentTest "works with multiple object relationships" $ \performGraphqlRequest -> do
|
||||
let headers = []
|
||||
let graphqlRequest =
|
||||
[graphql|
|
||||
query getTrack {
|
||||
Track(limit: 1) {
|
||||
Name
|
||||
Genre {
|
||||
Name
|
||||
}
|
||||
MediaType {
|
||||
Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|]
|
||||
let queryResponse =
|
||||
rowsResponse
|
||||
[ [ (API.FieldName "Name", API.mkColumnFieldValue $ Aeson.String "For Those About To Rock (We Salute You)"),
|
||||
( API.FieldName "Genre",
|
||||
API.mkRelationshipFieldValue $
|
||||
rowsResponse
|
||||
[ [(API.FieldName "Name", API.mkColumnFieldValue $ Aeson.String "Rock")]
|
||||
]
|
||||
),
|
||||
( API.FieldName "MediaType",
|
||||
API.mkRelationshipFieldValue $
|
||||
rowsResponse
|
||||
[ [(API.FieldName "Name", API.mkColumnFieldValue $ Aeson.String "MPEG audio file")]
|
||||
]
|
||||
)
|
||||
]
|
||||
]
|
||||
let mockConfig = Mock.chinookMock & mockQueryResponse queryResponse
|
||||
|
||||
MockRequestResults {..} <- performGraphqlRequest mockConfig headers graphqlRequest
|
||||
|
||||
_mrrGraphqlResponse
|
||||
`shouldBeYaml` [yaml|
|
||||
data:
|
||||
Track:
|
||||
- Genre:
|
||||
Name: "Rock"
|
||||
MediaType:
|
||||
Name: "MPEG audio file"
|
||||
Name: "For Those About To Rock (We Salute You)"
|
||||
|]
|
||||
|
||||
_mrrRecordedRequest
|
||||
`shouldBe` Just
|
||||
( Query $
|
||||
API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Track" :| []),
|
||||
_qrTableRelationships =
|
||||
[ API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Track" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "Genre",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Genre" :| []),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "GenreId", API.ColumnName "GenreId")]
|
||||
}
|
||||
),
|
||||
( API.FieldName "MediaType",
|
||||
API.mkRelationshipFieldValue $
|
||||
rowsResponse
|
||||
[ [(API.FieldName "Name", API.mkColumnFieldValue $ Aeson.String "MPEG audio file")]
|
||||
]
|
||||
( API.RelationshipName "MediaType",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("MediaType" :| []),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping =
|
||||
HashMap.fromList
|
||||
[(API.ColumnName "MediaTypeId", API.ColumnName "MediaTypeId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
]
|
||||
in Mock.chinookMock {Mock._queryResponse = \_ -> Right (rowsResponse albums)},
|
||||
_whenRequestRequired =
|
||||
[graphql|
|
||||
query getTrack {
|
||||
Track(limit: 1) {
|
||||
Name
|
||||
Genre {
|
||||
Name
|
||||
}
|
||||
MediaType {
|
||||
Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|],
|
||||
_thenRequired =
|
||||
[yaml|
|
||||
data:
|
||||
Track:
|
||||
- Genre:
|
||||
Name: "Rock"
|
||||
MediaType:
|
||||
Name: "MPEG audio file"
|
||||
Name: "For Those About To Rock (We Salute You)"
|
||||
|]
|
||||
}
|
||||
in (Mock.defaultTestCase required)
|
||||
{ _whenQuery =
|
||||
Just
|
||||
( API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Track" :| []),
|
||||
_qrTableRelationships =
|
||||
[ API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Track" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "Genre",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Genre" :| []),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "GenreId", API.ColumnName "GenreId")]
|
||||
}
|
||||
),
|
||||
( API.RelationshipName "MediaType",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("MediaType" :| []),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping =
|
||||
HashMap.fromList
|
||||
[(API.ColumnName "MediaTypeId", API.ColumnName "MediaTypeId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string"),
|
||||
( API.FieldName "Genre",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "Genre")
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
),
|
||||
( API.FieldName "MediaType",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "MediaType")
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
)
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
it "works with an order by that navigates relationships" $
|
||||
Mock.runTest opts $
|
||||
let required =
|
||||
Mock.TestCaseRequired
|
||||
{ _givenRequired =
|
||||
let albums =
|
||||
[ [ ( API.FieldName "Album",
|
||||
API.mkRelationshipFieldValue $
|
||||
rowsResponse
|
||||
[ [ ( API.FieldName "Artist",
|
||||
API.mkRelationshipFieldValue $
|
||||
rowsResponse
|
||||
[[(API.FieldName "Name", API.mkColumnFieldValue $ Aeson.String "Zeca Pagodinho")]]
|
||||
)
|
||||
]
|
||||
]
|
||||
],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string"),
|
||||
( API.FieldName "Genre",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "Genre")
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
),
|
||||
(API.FieldName "Name", API.mkColumnFieldValue $ Aeson.String "Camarão que Dorme e Onda Leva")
|
||||
]
|
||||
]
|
||||
in Mock.chinookMock {Mock._queryResponse = \_ -> Right (rowsResponse albums)},
|
||||
_whenRequestRequired =
|
||||
[graphql|
|
||||
query getTrack {
|
||||
Track(order_by: [{Album: {Artist: {Name: desc}}}, { Name: asc }], limit: 1) {
|
||||
Album {
|
||||
Artist {
|
||||
Name
|
||||
}
|
||||
}
|
||||
Name
|
||||
}
|
||||
}
|
||||
|],
|
||||
_thenRequired =
|
||||
[yaml|
|
||||
data:
|
||||
Track:
|
||||
- Album:
|
||||
Artist:
|
||||
Name: Zeca Pagodinho
|
||||
Name: Camarão que Dorme e Onda Leva
|
||||
|]
|
||||
}
|
||||
in (Mock.defaultTestCase required)
|
||||
{ _whenQuery =
|
||||
Just
|
||||
( API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Track" :| []),
|
||||
_qrTableRelationships =
|
||||
[ API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Track" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "Album",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Album" :| []),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "AlbumId", API.ColumnName "AlbumId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Album" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "Artist",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Artist" :| []),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
( API.FieldName "MediaType",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "MediaType")
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
)
|
||||
],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string"),
|
||||
( API.FieldName "Album",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "Album")
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ ( API.FieldName "Artist",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "Artist")
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
)
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
)
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy =
|
||||
Just $
|
||||
API.OrderBy
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
mockAgentTest "works with an order by that navigates relationships" $ \performGraphqlRequest -> do
|
||||
let headers = []
|
||||
let graphqlRequest =
|
||||
[graphql|
|
||||
query getTrack {
|
||||
Track(order_by: [{Album: {Artist: {Name: desc}}}, { Name: asc }], limit: 1) {
|
||||
Album {
|
||||
Artist {
|
||||
Name
|
||||
}
|
||||
}
|
||||
Name
|
||||
}
|
||||
}
|
||||
|]
|
||||
let queryResponse =
|
||||
rowsResponse
|
||||
[ [ ( API.FieldName "Album",
|
||||
API.mkRelationshipFieldValue $
|
||||
rowsResponse
|
||||
[ [ ( API.FieldName "Artist",
|
||||
API.mkRelationshipFieldValue $
|
||||
rowsResponse
|
||||
[[(API.FieldName "Name", API.mkColumnFieldValue $ Aeson.String "Zeca Pagodinho")]]
|
||||
)
|
||||
]
|
||||
]
|
||||
),
|
||||
(API.FieldName "Name", API.mkColumnFieldValue $ Aeson.String "Camarão que Dorme e Onda Leva")
|
||||
]
|
||||
]
|
||||
let mockConfig = Mock.chinookMock & mockQueryResponse queryResponse
|
||||
|
||||
MockRequestResults {..} <- performGraphqlRequest mockConfig headers graphqlRequest
|
||||
|
||||
_mrrGraphqlResponse
|
||||
`shouldBeYaml` [yaml|
|
||||
data:
|
||||
Track:
|
||||
- Album:
|
||||
Artist:
|
||||
Name: Zeca Pagodinho
|
||||
Name: Camarão que Dorme e Onda Leva
|
||||
|]
|
||||
|
||||
_mrrRecordedRequest
|
||||
`shouldBe` Just
|
||||
( Query $
|
||||
API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Track" :| []),
|
||||
_qrTableRelationships =
|
||||
[ API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Track" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "Album",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Album" :| []),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "AlbumId", API.ColumnName "AlbumId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Album" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "Artist",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Artist" :| []),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "ArtistId", API.ColumnName "ArtistId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string"),
|
||||
( API.FieldName "Album",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "Album")
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ ( API.FieldName "Artist",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
(API.RelationshipName "Artist")
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
)
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
)
|
||||
)
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy =
|
||||
Just $
|
||||
API.OrderBy
|
||||
( HashMap.fromList
|
||||
[ ( API.RelationshipName "Album",
|
||||
API.OrderByRelation
|
||||
Nothing
|
||||
( HashMap.fromList
|
||||
[ ( API.RelationshipName "Album",
|
||||
[ ( API.RelationshipName "Artist",
|
||||
API.OrderByRelation
|
||||
Nothing
|
||||
( HashMap.fromList
|
||||
[ ( API.RelationshipName "Artist",
|
||||
API.OrderByRelation
|
||||
Nothing
|
||||
mempty
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
( NE.fromList
|
||||
[ API.OrderByElement [API.RelationshipName "Album", API.RelationshipName "Artist"] (API.OrderByColumn (API.ColumnName "Name")) API.Descending,
|
||||
API.OrderByElement [] (API.OrderByColumn (API.ColumnName "Name")) API.Ascending
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
it "works with an order by that navigates a relationship with table permissions" $
|
||||
Mock.runTest opts $
|
||||
let required =
|
||||
Mock.TestCaseRequired
|
||||
{ _givenRequired =
|
||||
let albums =
|
||||
[ [ (API.FieldName "EmployeeId", API.mkColumnFieldValue $ Aeson.Number 3)
|
||||
]
|
||||
]
|
||||
in Mock.chinookMock {Mock._queryResponse = \_ -> Right (rowsResponse albums)},
|
||||
_whenRequestRequired =
|
||||
[graphql|
|
||||
query getEmployee {
|
||||
Employee(limit: 1, order_by: {SupportRepForCustomers_aggregate: {count: desc}}) {
|
||||
EmployeeId
|
||||
}
|
||||
}
|
||||
|],
|
||||
_thenRequired =
|
||||
[yaml|
|
||||
data:
|
||||
Employee:
|
||||
- EmployeeId: 3
|
||||
|]
|
||||
}
|
||||
in (Mock.defaultTestCase required)
|
||||
{ _whenRequestHeaders = [("X-Hasura-Role", testRoleName)],
|
||||
_whenQuery =
|
||||
Just
|
||||
( API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Employee" :| []),
|
||||
_qrTableRelationships =
|
||||
[ API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Customer" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "SupportRep",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Employee" :| []),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "SupportRepId", API.ColumnName "EmployeeId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Employee" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "SupportRepForCustomers",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Customer" :| []),
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "EmployeeId", API.ColumnName "SupportRepId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "EmployeeId", API.ColumnField (API.ColumnName "EmployeeId") $ API.ScalarType "number")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere =
|
||||
Just $
|
||||
API.Exists (API.RelatedTable $ API.RelationshipName "SupportRepForCustomers") $
|
||||
API.ApplyBinaryComparisonOperator
|
||||
API.Equal
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") $ API.ScalarType "string")
|
||||
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") $ API.ScalarType "string")),
|
||||
_qOrderBy =
|
||||
Just $
|
||||
API.OrderBy
|
||||
( HashMap.fromList
|
||||
[ ( API.RelationshipName "SupportRepForCustomers",
|
||||
API.OrderByRelation
|
||||
( Just $
|
||||
API.Exists (API.RelatedTable $ API.RelationshipName "SupportRep") $
|
||||
API.ApplyBinaryComparisonOperator
|
||||
API.Equal
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") $ API.ScalarType "string")
|
||||
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") $ API.ScalarType "string"))
|
||||
)
|
||||
mempty
|
||||
)
|
||||
]
|
||||
)
|
||||
(API.OrderByElement [API.RelationshipName "SupportRepForCustomers"] API.OrderByStarCountAggregate API.Descending :| [])
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
( NE.fromList
|
||||
[ API.OrderByElement [API.RelationshipName "Album", API.RelationshipName "Artist"] (API.OrderByColumn (API.ColumnName "Name")) API.Descending,
|
||||
API.OrderByElement [] (API.OrderByColumn (API.ColumnName "Name")) API.Ascending
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
mockAgentTest "works with an order by that navigates a relationship with table permissions" $ \performGraphqlRequest -> do
|
||||
let headers = [("X-Hasura-Role", testRoleName)]
|
||||
let graphqlRequest =
|
||||
[graphql|
|
||||
query getEmployee {
|
||||
Employee(limit: 1, order_by: {SupportRepForCustomers_aggregate: {count: desc}}) {
|
||||
EmployeeId
|
||||
}
|
||||
}
|
||||
|]
|
||||
let queryResponse =
|
||||
rowsResponse
|
||||
[ [ (API.FieldName "EmployeeId", API.mkColumnFieldValue $ Aeson.Number 3)
|
||||
]
|
||||
]
|
||||
let mockConfig = Mock.chinookMock & mockQueryResponse queryResponse
|
||||
|
||||
MockRequestResults {..} <- performGraphqlRequest mockConfig headers graphqlRequest
|
||||
|
||||
_mrrGraphqlResponse
|
||||
`shouldBeYaml` [yaml|
|
||||
data:
|
||||
Employee:
|
||||
- EmployeeId: 3
|
||||
|]
|
||||
|
||||
_mrrRecordedRequest
|
||||
`shouldBe` Just
|
||||
( Query $
|
||||
API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Employee" :| []),
|
||||
_qrTableRelationships =
|
||||
[ API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Customer" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "SupportRep",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Employee" :| []),
|
||||
_rRelationshipType = API.ObjectRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "SupportRepId", API.ColumnName "EmployeeId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
API.TableRelationships
|
||||
{ _trSourceTable = API.TableName ("Employee" :| []),
|
||||
_trRelationships =
|
||||
HashMap.fromList
|
||||
[ ( API.RelationshipName "SupportRepForCustomers",
|
||||
API.Relationship
|
||||
{ _rTargetTable = API.TableName ("Customer" :| []),
|
||||
_rRelationshipType = API.ArrayRelationship,
|
||||
_rColumnMapping = HashMap.fromList [(API.ColumnName "EmployeeId", API.ColumnName "SupportRepId")]
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "EmployeeId", API.ColumnField (API.ColumnName "EmployeeId") $ API.ScalarType "number")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere =
|
||||
Just $
|
||||
API.Exists (API.RelatedTable $ API.RelationshipName "SupportRepForCustomers") $
|
||||
API.ApplyBinaryComparisonOperator
|
||||
API.Equal
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") $ API.ScalarType "string")
|
||||
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") $ API.ScalarType "string")),
|
||||
_qOrderBy =
|
||||
Just $
|
||||
API.OrderBy
|
||||
( HashMap.fromList
|
||||
[ ( API.RelationshipName "SupportRepForCustomers",
|
||||
API.OrderByRelation
|
||||
( Just $
|
||||
API.Exists (API.RelatedTable $ API.RelationshipName "SupportRep") $
|
||||
API.ApplyBinaryComparisonOperator
|
||||
API.Equal
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") $ API.ScalarType "string")
|
||||
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") $ API.ScalarType "string"))
|
||||
)
|
||||
mempty
|
||||
)
|
||||
]
|
||||
)
|
||||
(API.OrderByElement [API.RelationshipName "SupportRepForCustomers"] API.OrderByStarCountAggregate API.Descending :| [])
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
rowsResponse :: [[(API.FieldName, API.FieldValue)]] -> API.QueryResponse
|
||||
rowsResponse rows = API.QueryResponse (Just $ HashMap.fromList <$> rows) Nothing
|
||||
|
@ -8,16 +8,17 @@ module Test.DataConnector.MockAgent.TransformedConfigurationSpec (spec) where
|
||||
import Data.Aeson qualified as Aeson
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Data.List.NonEmpty qualified as NE
|
||||
import Harness.Backend.DataConnector.Mock (TestCase (..))
|
||||
import Harness.Backend.DataConnector.Mock (AgentRequest (..), MockRequestResults (..), mockAgentTest, mockQueryResponse)
|
||||
import Harness.Backend.DataConnector.Mock qualified as Mock
|
||||
import Harness.Quoter.Graphql (graphql)
|
||||
import Harness.Quoter.Yaml (yaml)
|
||||
import Harness.Test.BackendType qualified as BackendType
|
||||
import Harness.Test.Fixture qualified as Fixture
|
||||
import Harness.TestEnvironment (GlobalTestEnvironment, TestEnvironment)
|
||||
import Harness.Yaml (shouldBeYaml)
|
||||
import Hasura.Backends.DataConnector.API qualified as API
|
||||
import Hasura.Prelude
|
||||
import Test.Hspec (SpecWith, describe, it)
|
||||
import Test.Hspec (SpecWith, describe, shouldBe)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -99,72 +100,66 @@ sourceMetadata =
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
tests :: Fixture.Options -> SpecWith (TestEnvironment, Mock.MockAgentEnvironment)
|
||||
tests opts = do
|
||||
describe "Basic Tests" $ do
|
||||
it "works with configuration transformation Kriti template" $
|
||||
Mock.runTest opts $
|
||||
let required =
|
||||
Mock.TestCaseRequired
|
||||
{ _givenRequired =
|
||||
let albums =
|
||||
[ [ (API.FieldName "id", API.mkColumnFieldValue $ Aeson.Number 1),
|
||||
(API.FieldName "title", API.mkColumnFieldValue $ Aeson.String "For Those About To Rock We Salute You")
|
||||
]
|
||||
]
|
||||
in Mock.chinookMock {Mock._queryResponse = \_ -> Right (rowsResponse albums)},
|
||||
_whenRequestRequired =
|
||||
[graphql|
|
||||
query getAlbum {
|
||||
albums(limit: 1) {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
|],
|
||||
_thenRequired =
|
||||
[yaml|
|
||||
data:
|
||||
albums:
|
||||
- id: 1
|
||||
title: For Those About To Rock We Salute You
|
||||
|]
|
||||
}
|
||||
in (Mock.defaultTestCase required)
|
||||
{ _whenQuery =
|
||||
Just
|
||||
( API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Album" :| []),
|
||||
_qrTableRelationships = [],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
),
|
||||
_whenConfig =
|
||||
-- TODO: Create a QQ for this purpose.
|
||||
let conf =
|
||||
Aeson.fromJSON
|
||||
[yaml|
|
||||
DEBUG:
|
||||
config: "baz config default"
|
||||
env: "bar env default"
|
||||
session: "foo session default"
|
||||
|]
|
||||
in case conf of
|
||||
Aeson.Success r -> Just r
|
||||
_ -> error "Should parse."
|
||||
tests _opts = describe "Transformed Configuration Tests" $ do
|
||||
mockAgentTest "works with configuration transformation Kriti template" $ \performGraphqlRequest -> do
|
||||
let headers = []
|
||||
let graphqlRequest =
|
||||
[graphql|
|
||||
query getAlbum {
|
||||
albums(limit: 1) {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
|]
|
||||
let queryResponse =
|
||||
rowsResponse
|
||||
[ [ (API.FieldName "id", API.mkColumnFieldValue $ Aeson.Number 1),
|
||||
(API.FieldName "title", API.mkColumnFieldValue $ Aeson.String "For Those About To Rock We Salute You")
|
||||
]
|
||||
]
|
||||
let mockConfig = Mock.chinookMock & mockQueryResponse queryResponse
|
||||
|
||||
MockRequestResults {..} <- performGraphqlRequest mockConfig headers graphqlRequest
|
||||
|
||||
_mrrGraphqlResponse
|
||||
`shouldBeYaml` [yaml|
|
||||
data:
|
||||
albums:
|
||||
- id: 1
|
||||
title: For Those About To Rock We Salute You
|
||||
|]
|
||||
|
||||
_mrrRecordedRequest
|
||||
`shouldBe` Just
|
||||
( Query $
|
||||
API.QueryRequest
|
||||
{ _qrTable = API.TableName ("Album" :| []),
|
||||
_qrTableRelationships = [],
|
||||
_qrQuery =
|
||||
API.Query
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
_qOffset = Nothing,
|
||||
_qWhere = Nothing,
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Aeson.toJSON _mrrRecordedRequestConfig
|
||||
`shouldBeYaml` [yaml|
|
||||
DEBUG:
|
||||
config: "baz config default"
|
||||
env: "bar env default"
|
||||
session: "foo session default"
|
||||
|]
|
||||
|
||||
rowsResponse :: [[(API.FieldName, API.FieldValue)]] -> API.QueryResponse
|
||||
rowsResponse rows = API.QueryResponse (Just $ HashMap.fromList <$> rows) Nothing
|
||||
|
@ -13,11 +13,7 @@ module Harness.Backend.DataConnector.Mock
|
||||
-- * Mock Test Construction
|
||||
MockConfig (..),
|
||||
MockAgentEnvironment (..),
|
||||
TestCase (..),
|
||||
TestCaseRequired (..),
|
||||
runTest,
|
||||
mockAgentPort,
|
||||
defaultTestCase,
|
||||
chinookMock,
|
||||
AgentRequest (..),
|
||||
MockRequestResults (..),
|
||||
@ -42,10 +38,9 @@ import Harness.Test.BackendType qualified as BackendType
|
||||
import Harness.Test.Fixture qualified as Fixture
|
||||
import Harness.Test.TestResource (AcquiredResource (..), Managed, mkTestResource)
|
||||
import Harness.TestEnvironment (TestEnvironment (..))
|
||||
import Harness.Yaml (shouldReturnYaml)
|
||||
import Hasura.Backends.DataConnector.API qualified as API
|
||||
import Hasura.Prelude
|
||||
import Test.Hspec (Arg, Expectation, SpecWith, it, shouldBe)
|
||||
import Test.Hspec (Arg, Expectation, SpecWith, it)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -89,10 +84,10 @@ agentConfig =
|
||||
let backendType = BackendType.backendTypeString backendTypeMetadata
|
||||
agentUri = "http://127.0.0.1:" <> show mockAgentPort <> "/"
|
||||
in [yaml|
|
||||
dataconnector:
|
||||
*backendType:
|
||||
uri: *agentUri
|
||||
|]
|
||||
dataconnector:
|
||||
*backendType:
|
||||
uri: *agentUri
|
||||
|]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Mock Agent
|
||||
@ -149,74 +144,6 @@ mkLocalTestEnvironment _ = mkTestResource do
|
||||
teardownResource = Async.cancel maeThread
|
||||
}
|
||||
|
||||
-- | Mock Agent test case input.
|
||||
data TestCase = TestCase
|
||||
{ -- | The Mock configuration for the agent
|
||||
_given :: MockConfig,
|
||||
-- | The Graphql Query to test
|
||||
_whenRequest :: Aeson.Value,
|
||||
-- | The headers to use on the Graphql Query request
|
||||
_whenRequestHeaders :: RequestHeaders,
|
||||
-- | The expected HGE 'API.Query' value to be provided to the
|
||||
-- agent. A @Nothing@ value indicates that the 'API.Query'
|
||||
-- assertion should be skipped.
|
||||
_whenQuery :: Maybe API.QueryRequest,
|
||||
-- | The expected HGE 'API.QueryHeaders' response and outgoing HGE 'API.QueryHeaders'
|
||||
_whenConfig :: Maybe API.Config,
|
||||
-- | The expected GQL response and outgoing HGE 'API.Query'
|
||||
_then :: Aeson.Value
|
||||
}
|
||||
|
||||
data TestCaseRequired = TestCaseRequired
|
||||
{ -- | The Mock configuration for the agent
|
||||
_givenRequired :: MockConfig,
|
||||
-- | The Graphql Query to test
|
||||
_whenRequestRequired :: Aeson.Value,
|
||||
-- | The expected GQL response and outgoing HGE 'API.Query'
|
||||
_thenRequired :: Aeson.Value
|
||||
}
|
||||
|
||||
defaultTestCase :: TestCaseRequired -> TestCase
|
||||
defaultTestCase TestCaseRequired {..} =
|
||||
TestCase
|
||||
{ _given = _givenRequired,
|
||||
_whenRequest = _whenRequestRequired,
|
||||
_whenRequestHeaders = [],
|
||||
_whenQuery = Nothing,
|
||||
_whenConfig = Nothing,
|
||||
_then = _thenRequired
|
||||
}
|
||||
|
||||
-- | Test runner for the Mock Agent. 'runMockedTest' sets the mocked
|
||||
-- value in the agent, fires a GQL request, then asserts on the
|
||||
-- expected response and 'API.Query' value.
|
||||
runTest :: HasCallStack => Fixture.Options -> TestCase -> (TestEnvironment, MockAgentEnvironment) -> IO ()
|
||||
runTest opts TestCase {..} (testEnvironment, MockAgentEnvironment {..}) = do
|
||||
-- Set the Agent with the 'MockConfig'
|
||||
I.writeIORef maeConfig _given
|
||||
|
||||
-- Execute the GQL Query and assert on the result
|
||||
shouldReturnYaml
|
||||
opts
|
||||
( GraphqlEngine.postGraphqlWithHeaders
|
||||
testEnvironment
|
||||
_whenRequestHeaders
|
||||
_whenRequest
|
||||
)
|
||||
_then
|
||||
|
||||
-- Read the logged 'API.QueryRequest' from the Agent
|
||||
query <- (>>= \case Query query -> Just query; _ -> Nothing) <$> I.readIORef maeRecordedRequest
|
||||
I.writeIORef maeRecordedRequest Nothing
|
||||
|
||||
-- Read the logged 'API.Config' from the Agent
|
||||
queryConfig <- I.readIORef maeRecordedRequestConfig
|
||||
I.writeIORef maeRecordedRequestConfig Nothing
|
||||
|
||||
-- Assert that the 'API.QueryRequest' was constructed how we expected.
|
||||
for_ _whenQuery ((query `shouldBe`) . Just)
|
||||
for_ _whenConfig ((queryConfig `shouldBe`) . Just)
|
||||
|
||||
data MockRequestResults = MockRequestResults
|
||||
{ _mrrGraphqlResponse :: Aeson.Value,
|
||||
_mrrRecordedRequest :: Maybe AgentRequest,
|
||||
@ -231,11 +158,11 @@ mockMutationResponse :: API.MutationResponse -> MockConfig -> MockConfig
|
||||
mockMutationResponse mutationResponse mockConfig =
|
||||
mockConfig {_mutationResponse = \_ -> Right mutationResponse}
|
||||
|
||||
mockAgentTest :: String -> ((MockConfig -> RequestHeaders -> Aeson.Value -> IO MockRequestResults) -> Expectation) -> SpecWith (Arg ((TestEnvironment, MockAgentEnvironment) -> Expectation))
|
||||
mockAgentTest :: HasCallStack => String -> ((MockConfig -> RequestHeaders -> Aeson.Value -> IO MockRequestResults) -> Expectation) -> SpecWith (Arg ((TestEnvironment, MockAgentEnvironment) -> Expectation))
|
||||
mockAgentTest name testBody =
|
||||
it name $ \env -> testBody (postMockAgentGraphqlWithHeaders env)
|
||||
|
||||
postMockAgentGraphqlWithHeaders :: (TestEnvironment, MockAgentEnvironment) -> MockConfig -> RequestHeaders -> Aeson.Value -> IO MockRequestResults
|
||||
postMockAgentGraphqlWithHeaders :: HasCallStack => (TestEnvironment, MockAgentEnvironment) -> MockConfig -> RequestHeaders -> Aeson.Value -> IO MockRequestResults
|
||||
postMockAgentGraphqlWithHeaders (testEnvironment, MockAgentEnvironment {..}) mockConfig requestHeaders graphqlRequest = do
|
||||
-- Set the Agent with the 'MockConfig'
|
||||
I.writeIORef maeConfig mockConfig
|
||||
|
Loading…
Reference in New Issue
Block a user