Adds an agent test for ordering by a single column aggregate function

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7820
GitOrigin-RevId: 8455c2ba032173ade474f2744b43d1259f88c9b2
This commit is contained in:
Daniel Chambers 2023-02-07 10:44:30 +11:00 committed by hasura-bot
parent f1091a9aff
commit 2e8fc69394
2 changed files with 55 additions and 1 deletions

View File

@ -25,6 +25,7 @@ module Test.Data
_ColumnFieldNumber,
_ColumnFieldString,
_ColumnFieldBoolean,
_ColumnFieldNull,
_RelationshipFieldRows,
orderByColumn,
)
@ -36,7 +37,7 @@ import Control.Arrow (first, (>>>))
import Control.Lens (Index, IxValue, Ixed, Traversal', ix, lens, (%~), (&), (^.), (^..), (^?), _Just)
import Data.Aeson (eitherDecodeStrict)
import Data.Aeson qualified as J
import Data.Aeson.Lens (_Bool, _Number, _String)
import Data.Aeson.Lens (_Bool, _Null, _Number, _String)
import Data.Bifunctor (bimap)
import Data.ByteString (ByteString)
import Data.ByteString.Lazy qualified as BSL
@ -518,6 +519,9 @@ _ColumnFieldString = API._ColumnFieldValue . _String
_ColumnFieldBoolean :: Traversal' API.FieldValue Bool
_ColumnFieldBoolean = API._ColumnFieldValue . _Bool
_ColumnFieldNull :: Traversal' API.FieldValue ()
_ColumnFieldNull = API._ColumnFieldValue . _Null
_RelationshipFieldRows :: Traversal' API.FieldValue [HashMap API.FieldName API.FieldValue]
_RelationshipFieldRows = API._RelationshipFieldValue . API.qrRows . _Just

View File

@ -1,3 +1,5 @@
{-# LANGUAGE QuasiQuotes #-}
module Test.Specs.QuerySpec.OrderBySpec (spec) where
import Control.Arrow ((>>>))
@ -12,6 +14,7 @@ import Data.List.NonEmpty qualified as NonEmpty
import Data.Maybe (fromMaybe, isJust)
import Data.Ord (Down (..))
import Hasura.Backends.DataConnector.API
import Language.GraphQL.Draft.Syntax.QQ qualified as G
import Test.AgentAPI (queryGuarded)
import Test.Data (TestData (..))
import Test.Data qualified as Data
@ -357,6 +360,49 @@ spec TestData {..} Capabilities {..} = describe "Order By in Queries" $ do
Data.responseRows receivedAlbums `rowsShouldBe` expectedArtists
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
it "can order results by an aggregate function applied to a column of a related table" $ do
-- Order artists by their highest album id descending, but only artists that have any albums
let orderByRelations =
HashMap.fromList
[ ( _tdAlbumsRelationshipName,
OrderByRelation
Nothing
mempty
)
]
let orderBy =
OrderBy orderByRelations $
NonEmpty.fromList
[ OrderByElement [_tdAlbumsRelationshipName] (orderBySingleColumnAggregateMax (_tdColumnName "AlbumId") albumIdNameScalarType) Descending
]
let whereExp =
Exists
(RelatedTable _tdAlbumsRelationshipName)
(Not $ ApplyUnaryComparisonOperator IsNull (_tdCurrentComparisonColumn "AlbumId" albumIdNameScalarType))
let query =
artistsQueryRequest
& qrQuery . qOrderBy ?~ orderBy
& qrQuery . qWhere ?~ whereExp
& qrTableRelationships
.~ [ Data.onlyKeepRelationships [_tdAlbumsRelationshipName] _tdArtistsTableRelationships
]
receivedArtists <- queryGuarded query
let findRelatedAlbums (artist :: HashMap FieldName FieldValue) = fromMaybe [] do
artistId <- artist ^? Data.field "ArtistId" . Data._ColumnFieldNumber
pure $ filter (\album -> album ^? Data.field "ArtistId" . Data._ColumnFieldNumber == Just artistId) _tdAlbumsRows
let expectedArtists =
_tdArtistsRows
& fmap (\artist -> (artist, findRelatedAlbums artist))
& filter (\(_artist, albums) -> any (\album -> album ^? Data.field "AlbumId" . Data._ColumnFieldNull /= Just ()) albums)
& fmap (\(artist, albums) -> (artist, maximum $ (albums & fmap (\album -> album ^? Data.field "AlbumId" . Data._ColumnFieldNumber))))
& sortOn (\row -> (Down (row ^. _2)))
& fmap (^. _1)
Data.responseRows receivedArtists `rowsShouldBe` expectedArtists
_qrAggregates receivedArtists `jsonShouldBe` Nothing
where
albumsQuery :: Query
albumsQuery =
@ -388,7 +434,11 @@ spec TestData {..} Capabilities {..} = describe "Order By in Queries" $ do
query = Data.emptyQuery & qFields ?~ fields
in QueryRequest _tdInvoicesTableName [] query
orderBySingleColumnAggregateMax :: ColumnName -> ScalarType -> OrderByTarget
orderBySingleColumnAggregateMax columnName resultType = OrderBySingleColumnAggregate $ SingleColumnAggregate (SingleColumnAggregateFunction [G.name|max|]) columnName resultType
albumTitleScalarType = _tdFindColumnScalarType _tdAlbumsTableName "Title"
albumIdNameScalarType = _tdFindColumnScalarType _tdAlbumsTableName "AlbumId"
artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name"
data NullableOrdered a