2022-07-22 12:46:25 +03:00
|
|
|
{-# LANGUAGE QuasiQuotes #-}
|
|
|
|
|
|
|
|
module Test.DataConnector.AggregateQuerySpec
|
|
|
|
( spec,
|
|
|
|
)
|
|
|
|
where
|
|
|
|
|
|
|
|
import Data.Aeson qualified as Aeson
|
2022-08-11 18:03:04 +03:00
|
|
|
import Data.List.NonEmpty qualified as NE
|
2022-07-22 12:46:25 +03:00
|
|
|
import Harness.Backend.DataConnector qualified as DataConnector
|
|
|
|
import Harness.GraphqlEngine qualified as GraphqlEngine
|
|
|
|
import Harness.Quoter.Graphql (graphql)
|
2022-08-05 12:34:25 +03:00
|
|
|
import Harness.Quoter.Yaml (yaml)
|
2022-07-22 12:46:25 +03:00
|
|
|
import Harness.Test.BackendType (BackendType (..), defaultBackendTypeString, defaultSource)
|
2022-08-10 10:52:57 +03:00
|
|
|
import Harness.Test.Fixture qualified as Fixture
|
2022-07-22 12:46:25 +03:00
|
|
|
import Harness.TestEnvironment (TestEnvironment)
|
2022-08-05 12:34:25 +03:00
|
|
|
import Harness.Yaml (shouldReturnYaml)
|
2022-08-03 17:18:43 +03:00
|
|
|
import Hasura.Prelude
|
2022-07-22 12:46:25 +03:00
|
|
|
import Test.Hspec (SpecWith, describe, it)
|
|
|
|
|
|
|
|
spec :: SpecWith TestEnvironment
|
|
|
|
spec =
|
2022-08-10 10:52:57 +03:00
|
|
|
Fixture.runWithLocalTestEnvironment
|
2022-08-11 18:03:04 +03:00
|
|
|
( NE.fromList
|
|
|
|
[ (Fixture.fixture $ Fixture.Backend Fixture.DataConnector)
|
|
|
|
{ Fixture.setupTeardown = \(testEnv, _) ->
|
|
|
|
[ DataConnector.setupFixtureAction
|
|
|
|
sourceMetadata
|
|
|
|
DataConnector.defaultBackendConfig
|
|
|
|
testEnv
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
2022-08-03 17:18:43 +03:00
|
|
|
)
|
2022-07-22 12:46:25 +03:00
|
|
|
tests
|
|
|
|
|
|
|
|
sourceMetadata :: Aeson.Value
|
|
|
|
sourceMetadata =
|
|
|
|
let source = defaultSource DataConnector
|
|
|
|
backendType = defaultBackendTypeString DataConnector
|
|
|
|
in [yaml|
|
|
|
|
name : *source
|
|
|
|
kind: *backendType
|
|
|
|
tables:
|
2022-08-04 11:34:45 +03:00
|
|
|
- table: [Album]
|
2022-07-22 12:46:25 +03:00
|
|
|
object_relationships:
|
|
|
|
- name: Artist
|
|
|
|
using:
|
|
|
|
manual_configuration:
|
2022-08-04 11:34:45 +03:00
|
|
|
remote_table: [Artist]
|
2022-07-22 12:46:25 +03:00
|
|
|
column_mapping:
|
|
|
|
ArtistId: ArtistId
|
2022-08-04 11:34:45 +03:00
|
|
|
- table: [Artist]
|
2022-07-22 12:46:25 +03:00
|
|
|
array_relationships:
|
|
|
|
- name: Albums
|
|
|
|
using:
|
|
|
|
manual_configuration:
|
2022-08-04 11:34:45 +03:00
|
|
|
remote_table: [Album]
|
2022-07-22 12:46:25 +03:00
|
|
|
column_mapping:
|
|
|
|
ArtistId: ArtistId
|
2022-08-04 11:34:45 +03:00
|
|
|
- table: [Invoice]
|
2022-07-28 08:39:48 +03:00
|
|
|
array_relationships:
|
|
|
|
- name: InvoiceLines
|
|
|
|
using:
|
|
|
|
manual_configuration:
|
2022-08-04 11:34:45 +03:00
|
|
|
remote_table: [InvoiceLine]
|
2022-07-28 08:39:48 +03:00
|
|
|
column_mapping:
|
|
|
|
InvoiceId: InvoiceId
|
2022-08-04 11:34:45 +03:00
|
|
|
- table: [InvoiceLine]
|
2022-07-28 08:39:48 +03:00
|
|
|
object_relationships:
|
|
|
|
- name: Invoice
|
|
|
|
using:
|
|
|
|
manual_configuration:
|
2022-08-04 11:34:45 +03:00
|
|
|
remote_table: [Invoice]
|
2022-07-28 08:39:48 +03:00
|
|
|
column_mapping:
|
|
|
|
InvoiceId: InvoiceId
|
2022-07-22 12:46:25 +03:00
|
|
|
configuration: {}
|
|
|
|
|]
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
2022-08-10 10:52:57 +03:00
|
|
|
tests :: Fixture.Options -> SpecWith (TestEnvironment, a)
|
2022-07-28 08:39:48 +03:00
|
|
|
tests opts = describe "Aggregate Query Tests" $ do
|
|
|
|
describe "Nodes Tests" $ do
|
|
|
|
it "works with simple query" $ \(testEnvironment, _) ->
|
|
|
|
shouldReturnYaml
|
|
|
|
opts
|
|
|
|
( GraphqlEngine.postGraphql
|
|
|
|
testEnvironment
|
|
|
|
[graphql|
|
|
|
|
query getAlbum {
|
|
|
|
Album_aggregate(limit: 2) {
|
|
|
|
nodes {
|
|
|
|
AlbumId
|
|
|
|
Title
|
|
|
|
}
|
2022-07-22 12:46:25 +03:00
|
|
|
}
|
|
|
|
}
|
2022-07-28 08:39:48 +03:00
|
|
|
|]
|
|
|
|
)
|
|
|
|
[yaml|
|
|
|
|
data:
|
|
|
|
Album_aggregate:
|
|
|
|
nodes:
|
|
|
|
- AlbumId: 1
|
|
|
|
Title: For Those About To Rock We Salute You
|
|
|
|
- AlbumId: 2
|
|
|
|
Title: Balls to the Wall
|
|
|
|
|]
|
2022-07-22 12:46:25 +03:00
|
|
|
|
2022-07-28 08:39:48 +03:00
|
|
|
it "works with multiple nodes fields" $ \(testEnvironment, _) ->
|
|
|
|
shouldReturnYaml
|
|
|
|
opts
|
|
|
|
( GraphqlEngine.postGraphql
|
|
|
|
testEnvironment
|
|
|
|
[graphql|
|
|
|
|
query getAlbum {
|
|
|
|
Album_aggregate(limit: 2) {
|
|
|
|
AlbumIds: nodes {
|
|
|
|
AlbumId
|
|
|
|
}
|
|
|
|
Titles: nodes {
|
|
|
|
Title
|
|
|
|
}
|
2022-07-22 12:46:25 +03:00
|
|
|
}
|
2022-07-28 08:39:48 +03:00
|
|
|
}
|
|
|
|
|]
|
|
|
|
)
|
|
|
|
[yaml|
|
|
|
|
data:
|
|
|
|
Album_aggregate:
|
|
|
|
AlbumIds:
|
|
|
|
- AlbumId: 1
|
|
|
|
- AlbumId: 2
|
|
|
|
Titles:
|
|
|
|
- Title: For Those About To Rock We Salute You
|
|
|
|
- Title: Balls to the Wall
|
|
|
|
|]
|
|
|
|
|
|
|
|
it "works with object relations" $ \(testEnvironment, _) ->
|
|
|
|
shouldReturnYaml
|
|
|
|
opts
|
|
|
|
( GraphqlEngine.postGraphql
|
|
|
|
testEnvironment
|
|
|
|
[graphql|
|
|
|
|
query getAlbum {
|
|
|
|
Album_aggregate(limit: 2) {
|
|
|
|
nodes {
|
|
|
|
AlbumId
|
|
|
|
Artist {
|
|
|
|
Name
|
|
|
|
}
|
|
|
|
}
|
2022-07-22 12:46:25 +03:00
|
|
|
}
|
|
|
|
}
|
2022-07-28 08:39:48 +03:00
|
|
|
|]
|
|
|
|
)
|
|
|
|
[yaml|
|
|
|
|
data:
|
|
|
|
Album_aggregate:
|
|
|
|
nodes:
|
|
|
|
- AlbumId: 1
|
|
|
|
Artist:
|
|
|
|
Name: AC/DC
|
|
|
|
- AlbumId: 2
|
|
|
|
Artist:
|
|
|
|
Name: Accept
|
|
|
|
|]
|
2022-07-22 12:46:25 +03:00
|
|
|
|
2022-07-28 08:39:48 +03:00
|
|
|
it "works with array relations" $ \(testEnvironment, _) ->
|
|
|
|
shouldReturnYaml
|
|
|
|
opts
|
|
|
|
( GraphqlEngine.postGraphql
|
|
|
|
testEnvironment
|
|
|
|
[graphql|
|
|
|
|
query getArtist {
|
|
|
|
Artist_aggregate(limit: 2) {
|
|
|
|
nodes {
|
|
|
|
ArtistId
|
|
|
|
Albums: Albums_aggregate {
|
|
|
|
nodes {
|
|
|
|
Title
|
|
|
|
}
|
|
|
|
}
|
2022-07-22 12:46:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-07-28 08:39:48 +03:00
|
|
|
|]
|
|
|
|
)
|
|
|
|
[yaml|
|
|
|
|
data:
|
|
|
|
Artist_aggregate:
|
|
|
|
nodes:
|
|
|
|
- ArtistId: 1
|
|
|
|
Albums:
|
|
|
|
nodes:
|
|
|
|
- Title: For Those About To Rock We Salute You
|
|
|
|
- Title: Let There Be Rock
|
|
|
|
- ArtistId: 2
|
|
|
|
Albums:
|
|
|
|
nodes:
|
|
|
|
- Title: Balls to the Wall
|
|
|
|
- Title: Restless and Wild
|
|
|
|
|]
|
|
|
|
|
|
|
|
describe "Aggregate Tests" $ do
|
|
|
|
it "works with count queries" $ \(testEnvironment, _) ->
|
|
|
|
shouldReturnYaml
|
|
|
|
opts
|
|
|
|
( GraphqlEngine.postGraphql
|
|
|
|
testEnvironment
|
|
|
|
[graphql|
|
|
|
|
query getInvoices {
|
|
|
|
Invoice_aggregate {
|
|
|
|
aggregate {
|
|
|
|
count
|
2022-07-28 10:24:13 +03:00
|
|
|
countColumn: count(column: BillingState)
|
|
|
|
countColumnDistinct: count(column: BillingState, distinct: true)
|
2022-07-28 08:39:48 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|]
|
|
|
|
)
|
|
|
|
[yaml|
|
|
|
|
data:
|
|
|
|
Invoice_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 412
|
|
|
|
countColumn: 210
|
|
|
|
countColumnDistinct: 25
|
|
|
|
|]
|
2022-07-22 12:46:25 +03:00
|
|
|
|
2022-07-28 08:39:48 +03:00
|
|
|
it "works with single column queries" $ \(testEnvironment, _) ->
|
|
|
|
shouldReturnYaml
|
|
|
|
opts
|
|
|
|
( GraphqlEngine.postGraphql
|
|
|
|
testEnvironment
|
|
|
|
[graphql|
|
|
|
|
query getInvoices {
|
|
|
|
Invoice_aggregate {
|
|
|
|
aggregate {
|
|
|
|
max {
|
|
|
|
Total
|
|
|
|
}
|
|
|
|
min {
|
|
|
|
Total
|
|
|
|
}
|
|
|
|
stddev {
|
|
|
|
Total
|
|
|
|
}
|
|
|
|
stddev_pop {
|
|
|
|
Total
|
|
|
|
}
|
|
|
|
stddev_samp {
|
|
|
|
Total
|
|
|
|
}
|
|
|
|
sum {
|
|
|
|
Total
|
|
|
|
}
|
|
|
|
var_pop {
|
|
|
|
Total
|
|
|
|
}
|
|
|
|
var_samp {
|
|
|
|
Total
|
|
|
|
}
|
|
|
|
variance {
|
|
|
|
Total
|
2022-07-22 12:46:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-07-28 08:39:48 +03:00
|
|
|
|]
|
|
|
|
)
|
|
|
|
[yaml|
|
|
|
|
data:
|
|
|
|
Invoice_aggregate:
|
|
|
|
aggregate:
|
|
|
|
max:
|
|
|
|
Total: 25.86
|
|
|
|
min:
|
|
|
|
Total: 0.99
|
|
|
|
stddev:
|
|
|
|
Total: 4.745319693568103
|
|
|
|
stddev_pop:
|
|
|
|
Total: 4.739557311729622
|
|
|
|
stddev_samp:
|
|
|
|
Total: 4.745319693568103
|
|
|
|
sum:
|
|
|
|
Total: 2328.600000000004
|
|
|
|
var_pop:
|
|
|
|
Total: 22.463403511169727
|
|
|
|
var_samp:
|
|
|
|
Total: 22.518058994165273
|
|
|
|
variance:
|
|
|
|
Total: 22.518058994165273
|
|
|
|
|]
|
|
|
|
|
2022-08-02 03:22:05 +03:00
|
|
|
it "min and max works on string fields" $ \(testEnvironment, _) ->
|
|
|
|
shouldReturnYaml
|
|
|
|
opts
|
|
|
|
( GraphqlEngine.postGraphql
|
|
|
|
testEnvironment
|
|
|
|
[graphql|
|
|
|
|
query getArtists {
|
|
|
|
Artist_aggregate {
|
|
|
|
aggregate {
|
|
|
|
max {
|
|
|
|
Name
|
|
|
|
}
|
|
|
|
min {
|
|
|
|
Name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|]
|
|
|
|
)
|
|
|
|
[yaml|
|
|
|
|
data:
|
|
|
|
Artist_aggregate:
|
|
|
|
aggregate:
|
|
|
|
max:
|
|
|
|
Name: Zeca Pagodinho
|
|
|
|
min:
|
|
|
|
Name: A Cor Do Som
|
|
|
|
|]
|
|
|
|
|
2022-07-28 08:39:48 +03:00
|
|
|
it "works across array relationships from regular queries" $ \(testEnvironment, _) ->
|
|
|
|
shouldReturnYaml
|
|
|
|
opts
|
|
|
|
( GraphqlEngine.postGraphql
|
|
|
|
testEnvironment
|
|
|
|
[graphql|
|
|
|
|
query getInvoices {
|
|
|
|
Invoice(limit: 5) {
|
|
|
|
InvoiceId
|
|
|
|
InvoiceLines_aggregate {
|
|
|
|
aggregate {
|
|
|
|
count
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|]
|
|
|
|
)
|
|
|
|
[yaml|
|
|
|
|
data:
|
|
|
|
Invoice:
|
|
|
|
- InvoiceId: 1
|
|
|
|
InvoiceLines_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 2
|
|
|
|
- InvoiceId: 2
|
|
|
|
InvoiceLines_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 4
|
|
|
|
- InvoiceId: 3
|
|
|
|
InvoiceLines_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 6
|
|
|
|
- InvoiceId: 4
|
|
|
|
InvoiceLines_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 9
|
|
|
|
- InvoiceId: 5
|
|
|
|
InvoiceLines_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 14
|
|
|
|
|]
|
|
|
|
|
|
|
|
it "works across array relationships from aggregate queries via nodes" $ \(testEnvironment, _) ->
|
|
|
|
shouldReturnYaml
|
|
|
|
opts
|
|
|
|
( GraphqlEngine.postGraphql
|
|
|
|
testEnvironment
|
|
|
|
[graphql|
|
|
|
|
query getInvoices {
|
|
|
|
Invoice_aggregate(limit: 5) {
|
|
|
|
nodes {
|
|
|
|
InvoiceId
|
|
|
|
InvoiceLines_aggregate {
|
|
|
|
aggregate {
|
|
|
|
count
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|]
|
|
|
|
)
|
|
|
|
[yaml|
|
|
|
|
data:
|
|
|
|
Invoice_aggregate:
|
|
|
|
nodes:
|
|
|
|
- InvoiceId: 1
|
|
|
|
InvoiceLines_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 2
|
|
|
|
- InvoiceId: 2
|
|
|
|
InvoiceLines_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 4
|
|
|
|
- InvoiceId: 3
|
|
|
|
InvoiceLines_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 6
|
|
|
|
- InvoiceId: 4
|
|
|
|
InvoiceLines_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 9
|
|
|
|
- InvoiceId: 5
|
|
|
|
InvoiceLines_aggregate:
|
|
|
|
aggregate:
|
|
|
|
count: 14
|
|
|
|
|]
|