cli: fix formatting errors in query collection metadata

closes https://github.com/hasura/graphql-engine/issues/7616
closes https://github.com/hasura/graphql-engine/issues/8205

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3955
GitOrigin-RevId: dc97e23e78d522cb7ac4d57ad825526eaa90a4de
This commit is contained in:
Aravind K P 2022-03-31 19:31:47 +05:30 committed by hasura-bot
parent 127bdcdf5c
commit e46777b7ea
7 changed files with 150 additions and 20 deletions

View File

@ -6,6 +6,7 @@
- console: add support for setting aggregation query permissions for ms sql server - console: add support for setting aggregation query permissions for ms sql server
- cli: fix remote schema metadata formatting issues (#7608) - cli: fix remote schema metadata formatting issues (#7608)
- cli: fix query collections metadata formatting issues (#7616)
## v2.5.0-beta.1 ## v2.5.0-beta.1

View File

@ -11,6 +11,10 @@ import (
"github.com/hasura/graphql-engine/cli/v2" "github.com/hasura/graphql-engine/cli/v2"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"github.com/vektah/gqlparser/ast"
"github.com/vektah/gqlparser/formatter"
"github.com/vektah/gqlparser/parser"
) )
type QueryCollectionConfig struct { type QueryCollectionConfig struct {
@ -57,8 +61,59 @@ func (q *QueryCollectionConfig) Build() (map[string]interface{}, metadataobject.
return map[string]interface{}{q.Key(): obj}, nil return map[string]interface{}{q.Key(): obj}, nil
} }
type querycollection struct {
Name yaml.Node `yaml:"name,omitempty"`
Definition definition `yaml:"definition,omitempty"`
}
type definition struct {
Queries []query `yaml:"queries,omitempty"`
}
type query struct {
Name yaml.Node `yaml:"name,omitempty"`
Query string `yaml:"query,omitempty"`
}
func (q *QueryCollectionConfig) Export(metadata map[string]yaml.Node) (map[string][]byte, metadataobject.ErrParsingMetadataObject) { func (q *QueryCollectionConfig) Export(metadata map[string]yaml.Node) (map[string][]byte, metadataobject.ErrParsingMetadataObject) {
return metadataobject.DefaultExport(q, metadata, q.error, metadataobject.DefaultObjectTypeSequence) var value interface{}
if v, ok := metadata[q.Key()]; !ok {
value = []yaml.Node{}
} else {
var collections []querycollection
bs, err := yaml.Marshal(v)
if err != nil {
return nil, q.error(err)
}
if err := yaml.Unmarshal(bs, &collections); err != nil {
return nil, q.error(err)
}
for collectionIdx := range collections {
for queryIdx := range collections[collectionIdx].Definition.Queries {
buf := new(bytes.Buffer)
queryDoc, err := parser.ParseQuery(&ast.Source{
Input: collections[collectionIdx].Definition.Queries[queryIdx].Query,
})
if err != nil {
return nil, q.error(err)
}
gqlFormatter := formatter.NewFormatter(buf)
gqlFormatter.FormatQueryDocument(queryDoc)
if buf.Len() > 0 {
collections[collectionIdx].Definition.Queries[queryIdx].Query = buf.String()
}
}
}
value = collections
}
var buf bytes.Buffer
err := metadataobject.GetEncoder(&buf).Encode(value)
if err != nil {
return nil, q.error(err)
}
return map[string][]byte{
filepath.ToSlash(filepath.Join(q.BaseDirectory(), q.Filename())): buf.Bytes(),
}, nil
} }
func (q *QueryCollectionConfig) Key() string { func (q *QueryCollectionConfig) Key() string {

View File

@ -114,7 +114,6 @@ func TestQueryCollectionConfig_Export(t *testing.T) {
}, },
false, false,
}, },
{ {
"t2", "t2",
"can export metadata when query collections is not present in metadata", "can export metadata when query collections is not present in metadata",
@ -169,6 +168,33 @@ func TestQueryCollectionConfig_Export(t *testing.T) {
}, },
false, false,
}, },
{
"t4",
"can export and format metadata correctly on multiline queries",
fields{
MetadataDir: "metadata",
logger: logrus.New(),
},
args{
metadata: func() map[string]yaml.Node {
bs, err := ioutil.ReadFile("testdata/export_test/t4/metadata.json")
assert.NoError(t, err)
yamlbs, err := metadatautil.JSONToYAML(bs)
assert.NoError(t, err)
var v map[string]yaml.Node
assert.NoError(t, yaml.Unmarshal(yamlbs, &v))
return v
}(),
},
map[string][]byte{
"metadata/query_collections.yaml": func() []byte {
bs, err := ioutil.ReadFile("testdata/export_test/t4/want.query_collections.yaml")
assert.NoError(t, err)
return bs
}(),
},
false,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@ -180,6 +206,7 @@ func TestQueryCollectionConfig_Export(t *testing.T) {
if tt.wantErr { if tt.wantErr {
assert.Error(t, err) assert.Error(t, err)
} else { } else {
assert.NoError(t, err)
for k, v := range got { for k, v := range got {
assert.Contains(t, tt.want, k) assert.Contains(t, tt.want, k)
// uncomment to update golden files // uncomment to update golden files

View File

@ -18,7 +18,7 @@
} }
} }
- name: get-artists - name: get-artists
query: |- query: |
query getArtists { query getArtists {
artists { artists {
name name

View File

@ -0,0 +1,19 @@
{
"query_collections": [
{
"name": "allowed-queries",
"definition": {
"queries": [
{
"name": "getCompanies",
"query": "query MyQuery {\n company {\n company_addresses {\n address {\n address_line_1\n address_line_2\n city\n country\n postal_code\n state\n }\n }\n id\n name\n }\n}"
},
{
"name": "addCompany",
"query": "mutation MyQuery {\n insert_company(objects: {\n company_addresses: {\n data: {\n id: \"94909f0b-e9db-4ce6-809b-0de59463caf1\",\n address: {\n data: {\n address_line_1: \"16, swastik circle\", \n address_line_2: \"\", \n city: \"Ahmedabad\", \n country: \"india\", \n id: \"1354fd0e-cb95-49ae-97d4-9ebfa225e831\",\n postal_code: \"312203\", \n state: \"Gujarat\"\n },\n on_conflict: {constraint: address_pkey}\n }\n }\n }, \n name: \"cygnet\", \n id: \"81c20bdf-fc22-473b-9ffb-173f4d6c6da2\"\n }) {\n affected_rows\n }\n}"
}
]
}
}
]
}

View File

@ -0,0 +1,28 @@
- name: allowed-queries
definition:
queries:
- name: getCompanies
query: |
query MyQuery {
company {
company_addresses {
address {
address_line_1
address_line_2
city
country
postal_code
state
}
}
id
name
}
}
- name: addCompany
query: |
mutation MyQuery {
insert_company(objects: {company_addresses:{data:{id:"94909f0b-e9db-4ce6-809b-0de59463caf1",address:{data:{address_line_1:"16, swastik circle",address_line_2:"",city:"Ahmedabad",country:"india",id:"1354fd0e-cb95-49ae-97d4-9ebfa225e831",postal_code:"312203",state:"Gujarat"},on_conflict:{constraint:address_pkey}}}},name:"cygnet",id:"81c20bdf-fc22-473b-9ffb-173f4d6c6da2"}) {
affected_rows
}
}