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:
Daniel Chambers 2022-08-16 14:45:07 +10:00 committed by hasura-bot
parent a1d0be0d86
commit c6e7dff526
3 changed files with 100 additions and 98 deletions

View File

@ -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 ""

View File

@ -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

View File

@ -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 =