mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-10-05 22:37:52 +03:00
server: Data Connector agent test suite bugfixes
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5500 GitOrigin-RevId: 5bb1a326ecd7aa95cbbda3591d2a51dea605125a
This commit is contained in:
parent
a1d0be0d86
commit
c6e7dff526
@ -82,8 +82,8 @@ renderDiffString useColor actual expected =
|
||||
|
||||
explanation =
|
||||
[ "━━━",
|
||||
colorSpan Green "--- expected, but not present",
|
||||
colorSpan Red "+++ present, but not expected",
|
||||
colorSpan Red "--- present, but not expected",
|
||||
colorSpan Green "+++ expected, but not present",
|
||||
"━━━"
|
||||
]
|
||||
|
||||
@ -92,8 +92,8 @@ renderDiffString useColor actual expected =
|
||||
annotateDiffLine :: Diff String -> String
|
||||
annotateDiffLine = \case
|
||||
Both _ s -> " " ++ s
|
||||
First s -> colorSpan Green $ "--- " ++ s
|
||||
Second s -> colorSpan Red $ "+++ " ++ s
|
||||
First s -> colorSpan Red $ "--- " ++ s
|
||||
Second s -> colorSpan Green $ "+++ " ++ s
|
||||
|
||||
colorSpan c s = colorCode (SetColor Foreground Dull c) ++ s ++ colorCode Reset
|
||||
colorCode sgr = if useColor then setSGRCode [sgr] else ""
|
||||
|
@ -17,4 +17,4 @@ spec api sourceName config Capabilities {..} = do
|
||||
Test.QuerySpec.BasicSpec.spec api sourceName config
|
||||
when (isJust cRelationships) $
|
||||
Test.QuerySpec.RelationshipsSpec.spec api sourceName config
|
||||
Test.QuerySpec.AggregatesSpec.spec api sourceName config
|
||||
Test.QuerySpec.AggregatesSpec.spec api sourceName config cRelationships
|
||||
|
@ -2,13 +2,14 @@ module Test.QuerySpec.AggregatesSpec (spec) where
|
||||
|
||||
import Control.Arrow ((>>>))
|
||||
import Control.Lens (ix, (%~), (&), (?~), (^?))
|
||||
import Control.Monad (when)
|
||||
import Data.Aeson.KeyMap (KeyMap)
|
||||
import Data.Aeson.KeyMap qualified as KeyMap
|
||||
import Data.HashSet qualified as HashSet
|
||||
import Data.List (sortOn)
|
||||
import Data.List.NonEmpty (NonEmpty (..))
|
||||
import Data.List.NonEmpty qualified as NonEmpty
|
||||
import Data.Maybe (fromMaybe, mapMaybe)
|
||||
import Data.Maybe (fromMaybe, isJust, mapMaybe)
|
||||
import Data.Ord (Down (..))
|
||||
import Hasura.Backends.DataConnector.API
|
||||
import Servant.API (NamedRoutes)
|
||||
@ -18,8 +19,8 @@ import Test.Expectations (jsonShouldBe, rowsShouldBe)
|
||||
import Test.Hspec (Spec, describe, it)
|
||||
import Prelude
|
||||
|
||||
spec :: Client IO (NamedRoutes Routes) -> SourceName -> Config -> Spec
|
||||
spec api sourceName config = describe "Aggregate Queries" $ do
|
||||
spec :: Client IO (NamedRoutes Routes) -> SourceName -> Config -> Maybe RelationshipCapabilities -> Spec
|
||||
spec api sourceName config relationshipCapabilities = describe "Aggregate Queries" $ do
|
||||
describe "Star Count" $ do
|
||||
it "counts all rows" $ do
|
||||
let aggregates = KeyMap.fromList [("count_all", StarCount)]
|
||||
@ -252,110 +253,111 @@ spec api sourceName config = describe "Aggregate Queries" $ do
|
||||
Data.responseRows response `rowsShouldBe` expectedRows
|
||||
Data.responseAggregates response `jsonShouldBe` expectedAggregates
|
||||
|
||||
describe "Aggregates via Relationships" $ do
|
||||
it "can query aggregates via an array relationship" $ do
|
||||
let query = artistsWithAlbumsQuery id & qrQuery . qLimit ?~ 5
|
||||
receivedArtists <- (api // _query) sourceName config query
|
||||
when (isJust relationshipCapabilities) $
|
||||
describe "Aggregates via Relationships" $ do
|
||||
it "can query aggregates via an array relationship" $ do
|
||||
let query = artistsWithAlbumsQuery id & qrQuery . qLimit ?~ 5
|
||||
receivedArtists <- (api // _query) sourceName config query
|
||||
|
||||
let joinInAlbums (artist :: KeyMap FieldValue) = fromMaybe artist $ do
|
||||
artistId <- artist ^? ix "ArtistId" . Data._ColumnFieldNumber
|
||||
let albums =
|
||||
Data.albumsRows
|
||||
& filter ((^? ix "ArtistId" . Data._ColumnFieldNumber) >>> (== Just artistId))
|
||||
let aggregates = KeyMap.fromList [("count", Number . fromIntegral $ length albums)]
|
||||
pure $ KeyMap.insert "Albums" (mkSubqueryResponse Nothing (Just aggregates)) artist
|
||||
let joinInAlbums (artist :: KeyMap FieldValue) = fromMaybe artist $ do
|
||||
artistId <- artist ^? ix "ArtistId" . Data._ColumnFieldNumber
|
||||
let albums =
|
||||
Data.albumsRows
|
||||
& filter ((^? ix "ArtistId" . Data._ColumnFieldNumber) >>> (== Just artistId))
|
||||
let aggregates = KeyMap.fromList [("count", Number . fromIntegral $ length albums)]
|
||||
pure $ KeyMap.insert "Albums" (mkSubqueryResponse Nothing (Just aggregates)) artist
|
||||
|
||||
let expectedArtists =
|
||||
Data.artistsRows
|
||||
& take 5
|
||||
& fmap joinInAlbums
|
||||
let expectedArtists =
|
||||
Data.artistsRows
|
||||
& take 5
|
||||
& fmap joinInAlbums
|
||||
|
||||
Data.responseRows receivedArtists `rowsShouldBe` expectedArtists
|
||||
Data.responseAggregates receivedArtists `jsonShouldBe` mempty
|
||||
Data.responseRows receivedArtists `rowsShouldBe` expectedArtists
|
||||
Data.responseAggregates receivedArtists `jsonShouldBe` mempty
|
||||
|
||||
it "can query aggregates via an array relationship and include the rows in that relationship" $ do
|
||||
let albumFields =
|
||||
KeyMap.fromList
|
||||
[ ("AlbumId", Data.columnField "AlbumId"),
|
||||
("Title", Data.columnField "Title")
|
||||
]
|
||||
let query = artistsWithAlbumsQuery (qFields ?~ albumFields) & qrQuery . qLimit ?~ 5
|
||||
receivedArtists <- (api // _query) sourceName config query
|
||||
it "can query aggregates via an array relationship and include the rows in that relationship" $ do
|
||||
let albumFields =
|
||||
KeyMap.fromList
|
||||
[ ("AlbumId", Data.columnField "AlbumId"),
|
||||
("Title", Data.columnField "Title")
|
||||
]
|
||||
let query = artistsWithAlbumsQuery (qFields ?~ albumFields) & qrQuery . qLimit ?~ 5
|
||||
receivedArtists <- (api // _query) sourceName config query
|
||||
|
||||
let joinInAlbums (artist :: KeyMap FieldValue) = fromMaybe artist $ do
|
||||
artistId <- artist ^? ix "ArtistId" . Data._ColumnFieldNumber
|
||||
let albums =
|
||||
Data.albumsRows
|
||||
& filter ((^? ix "ArtistId" . Data._ColumnFieldNumber) >>> (== Just artistId))
|
||||
& Data.filterColumns ["AlbumId", "Title"]
|
||||
let aggregates = KeyMap.fromList [("count", Number . fromIntegral $ length albums)]
|
||||
pure $ KeyMap.insert "Albums" (mkSubqueryResponse (Just albums) (Just aggregates)) artist
|
||||
let joinInAlbums (artist :: KeyMap FieldValue) = fromMaybe artist $ do
|
||||
artistId <- artist ^? ix "ArtistId" . Data._ColumnFieldNumber
|
||||
let albums =
|
||||
Data.albumsRows
|
||||
& filter ((^? ix "ArtistId" . Data._ColumnFieldNumber) >>> (== Just artistId))
|
||||
& Data.filterColumns ["AlbumId", "Title"]
|
||||
let aggregates = KeyMap.fromList [("count", Number . fromIntegral $ length albums)]
|
||||
pure $ KeyMap.insert "Albums" (mkSubqueryResponse (Just albums) (Just aggregates)) artist
|
||||
|
||||
let expectedArtists =
|
||||
Data.artistsRows
|
||||
& take 5
|
||||
& fmap joinInAlbums
|
||||
let expectedArtists =
|
||||
Data.artistsRows
|
||||
& take 5
|
||||
& fmap joinInAlbums
|
||||
|
||||
Data.responseRows receivedArtists `rowsShouldBe` expectedArtists
|
||||
Data.responseAggregates receivedArtists `jsonShouldBe` mempty
|
||||
Data.responseRows receivedArtists `rowsShouldBe` expectedArtists
|
||||
Data.responseAggregates receivedArtists `jsonShouldBe` mempty
|
||||
|
||||
it "can query with many nested relationships, with aggregates at multiple levels, with filtering, pagination and ordering" $ do
|
||||
receivedArtists <- (api // _query) sourceName config deeplyNestedArtistsQuery
|
||||
it "can query with many nested relationships, with aggregates at multiple levels, with filtering, pagination and ordering" $ do
|
||||
receivedArtists <- (api // _query) sourceName config deeplyNestedArtistsQuery
|
||||
|
||||
let joinInMediaType (track :: KeyMap FieldValue) = fromMaybe track $ do
|
||||
mediaTypeId <- track ^? ix "MediaTypeId" . Data._ColumnFieldNumber
|
||||
let mediaTypes =
|
||||
Data.mediaTypesRows
|
||||
& filter ((^? ix "MediaTypeId" . Data._ColumnFieldNumber) >>> (== Just mediaTypeId))
|
||||
& Data.filterColumns ["Name"]
|
||||
pure $ KeyMap.insert "nodes_MediaType" (mkSubqueryResponse (Just mediaTypes) Nothing) track
|
||||
let joinInMediaType (track :: KeyMap FieldValue) = fromMaybe track $ do
|
||||
mediaTypeId <- track ^? ix "MediaTypeId" . Data._ColumnFieldNumber
|
||||
let mediaTypes =
|
||||
Data.mediaTypesRows
|
||||
& filter ((^? ix "MediaTypeId" . Data._ColumnFieldNumber) >>> (== Just mediaTypeId))
|
||||
& Data.filterColumns ["Name"]
|
||||
pure $ KeyMap.insert "nodes_MediaType" (mkSubqueryResponse (Just mediaTypes) Nothing) track
|
||||
|
||||
let joinInInvoiceLines (track :: KeyMap FieldValue) = fromMaybe track $ do
|
||||
trackId <- track ^? ix "TrackId" . Data._ColumnFieldNumber
|
||||
let invoiceLines =
|
||||
Data.invoiceLinesRows
|
||||
& filter ((^? ix "TrackId" . Data._ColumnFieldNumber) >>> (== Just trackId))
|
||||
let getQuantity invoiceLine = invoiceLine ^? ix "Quantity" . Data._ColumnFieldNumber
|
||||
let invoiceLinesAggregates = KeyMap.fromList [("aggregate_sum_Quantity", aggregate (Number . sum) $ mapMaybe getQuantity invoiceLines)]
|
||||
pure $ KeyMap.insert "nodes_InvoiceLines_aggregate" (mkSubqueryResponse Nothing (Just invoiceLinesAggregates)) track
|
||||
let joinInInvoiceLines (track :: KeyMap FieldValue) = fromMaybe track $ do
|
||||
trackId <- track ^? ix "TrackId" . Data._ColumnFieldNumber
|
||||
let invoiceLines =
|
||||
Data.invoiceLinesRows
|
||||
& filter ((^? ix "TrackId" . Data._ColumnFieldNumber) >>> (== Just trackId))
|
||||
let getQuantity invoiceLine = invoiceLine ^? ix "Quantity" . Data._ColumnFieldNumber
|
||||
let invoiceLinesAggregates = KeyMap.fromList [("aggregate_sum_Quantity", aggregate (Number . sum) $ mapMaybe getQuantity invoiceLines)]
|
||||
pure $ KeyMap.insert "nodes_InvoiceLines_aggregate" (mkSubqueryResponse Nothing (Just invoiceLinesAggregates)) track
|
||||
|
||||
let joinInTracks (album :: KeyMap FieldValue) = fromMaybe album $ do
|
||||
albumId <- album ^? ix "AlbumId" . Data._ColumnFieldNumber
|
||||
let tracks =
|
||||
Data.tracksRows
|
||||
& filter
|
||||
( \track ->
|
||||
track ^? ix "AlbumId" . Data._ColumnFieldNumber == Just albumId
|
||||
&& track ^? ix "Milliseconds" . Data._ColumnFieldNumber < Just 300000
|
||||
)
|
||||
& sortOn (Down . (^? ix "Name" . Data._ColumnFieldString))
|
||||
& fmap (joinInMediaType >>> joinInInvoiceLines)
|
||||
& Data.renameColumns [("Name", "nodes_Name")]
|
||||
& Data.filterColumns ["nodes_Name", "nodes_MediaType", "nodes_InvoiceLines_aggregate"]
|
||||
let tracksAggregates = KeyMap.fromList [("aggregate_count", Number . fromIntegral $ length tracks)]
|
||||
pure $ KeyMap.insert "nodes_Tracks_aggregate" (mkSubqueryResponse (Just tracks) (Just tracksAggregates)) album
|
||||
let joinInTracks (album :: KeyMap FieldValue) = fromMaybe album $ do
|
||||
albumId <- album ^? ix "AlbumId" . Data._ColumnFieldNumber
|
||||
let tracks =
|
||||
Data.tracksRows
|
||||
& filter
|
||||
( \track ->
|
||||
track ^? ix "AlbumId" . Data._ColumnFieldNumber == Just albumId
|
||||
&& track ^? ix "Milliseconds" . Data._ColumnFieldNumber < Just 300000
|
||||
)
|
||||
& sortOn (Down . (^? ix "Name" . Data._ColumnFieldString))
|
||||
& fmap (joinInMediaType >>> joinInInvoiceLines)
|
||||
& Data.renameColumns [("Name", "nodes_Name")]
|
||||
& Data.filterColumns ["nodes_Name", "nodes_MediaType", "nodes_InvoiceLines_aggregate"]
|
||||
let tracksAggregates = KeyMap.fromList [("aggregate_count", Number . fromIntegral $ length tracks)]
|
||||
pure $ KeyMap.insert "nodes_Tracks_aggregate" (mkSubqueryResponse (Just tracks) (Just tracksAggregates)) album
|
||||
|
||||
let joinInAlbums (artist :: KeyMap FieldValue) = fromMaybe artist $ do
|
||||
artistId <- artist ^? ix "ArtistId" . Data._ColumnFieldNumber
|
||||
let albums =
|
||||
Data.albumsRows
|
||||
& filter ((^? ix "ArtistId" . Data._ColumnFieldNumber) >>> (== Just artistId))
|
||||
& fmap joinInTracks
|
||||
& Data.renameColumns [("Title", "nodes_Title")]
|
||||
& Data.filterColumns ["nodes_Title", "nodes_Tracks_aggregate"]
|
||||
pure $ KeyMap.insert "Albums_aggregate" (mkSubqueryResponse (Just albums) Nothing) artist
|
||||
let joinInAlbums (artist :: KeyMap FieldValue) = fromMaybe artist $ do
|
||||
artistId <- artist ^? ix "ArtistId" . Data._ColumnFieldNumber
|
||||
let albums =
|
||||
Data.albumsRows
|
||||
& filter ((^? ix "ArtistId" . Data._ColumnFieldNumber) >>> (== Just artistId))
|
||||
& fmap joinInTracks
|
||||
& Data.renameColumns [("Title", "nodes_Title")]
|
||||
& Data.filterColumns ["nodes_Title", "nodes_Tracks_aggregate"]
|
||||
pure $ KeyMap.insert "Albums_aggregate" (mkSubqueryResponse (Just albums) Nothing) artist
|
||||
|
||||
let expectedArtists =
|
||||
Data.artistsRows
|
||||
& sortOn (Down . (^? ix "Name"))
|
||||
& filter ((^? ix "Name" . Data._ColumnFieldString) >>> (\name -> name > Just "A" && name < Just "B"))
|
||||
& drop 1
|
||||
& take 3
|
||||
& fmap joinInAlbums
|
||||
& Data.filterColumns ["Name", "Albums_aggregate"]
|
||||
let expectedArtists =
|
||||
Data.artistsRows
|
||||
& sortOn (Down . (^? ix "Name"))
|
||||
& filter ((^? ix "Name" . Data._ColumnFieldString) >>> (\name -> name > Just "A" && name < Just "B"))
|
||||
& drop 1
|
||||
& take 3
|
||||
& fmap joinInAlbums
|
||||
& Data.filterColumns ["Name", "Albums_aggregate"]
|
||||
|
||||
Data.responseRows receivedArtists `rowsShouldBe` expectedArtists
|
||||
Data.responseAggregates receivedArtists `jsonShouldBe` mempty
|
||||
Data.responseRows receivedArtists `rowsShouldBe` expectedArtists
|
||||
Data.responseAggregates receivedArtists `jsonShouldBe` mempty
|
||||
|
||||
artistsWithAlbumsQuery :: (Query -> Query) -> QueryRequest
|
||||
artistsWithAlbumsQuery modifySubquery =
|
||||
|
Loading…
Reference in New Issue
Block a user