-
Notifications
You must be signed in to change notification settings - Fork 4
/
hasura_integration_helpers.go
133 lines (108 loc) · 3.17 KB
/
hasura_integration_helpers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package hasura
import (
"bytes"
"context"
"os"
"testing"
"github.com/dipdup-net/go-lib/config"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
)
type ExpectedMetadata struct {
Tables []ExpectedTable `yaml:"tables" validate:"required"`
}
type ExpectedTable struct {
Name string `yaml:"name" validate:"required"`
Columns []string `yaml:"columns" validate:"required"`
}
func TestExpectedMetadataWithActual(
t *testing.T,
configPath string,
expectedMetadataPath string,
) {
var cfg config.Config
if err := config.Parse(configPath, &cfg); err != nil {
t.Fatalf("Error with reading configuratoin file: %s", err)
}
api := New(cfg.Hasura.URL, cfg.Hasura.Secret)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
metadata, err := api.ExportMetadata(ctx)
if err != nil {
t.Fatalf("Error with getting hasura metadata %e", err)
}
expectedMetadata, err := parseExpectedMetadata(expectedMetadataPath)
if err != nil {
t.Fatalf("Error with parsing expected metadata: %e", err)
}
// Go through `expectedMetadata` and assert that each object
// in that array is in `metadata` with corresponding columns.
for _, expectedTable := range expectedMetadata.Tables {
metadataTableColumns, err := getTableColumns(metadata, expectedTable.Name, cfg.Hasura.Source.Name, "user")
if err != nil {
t.Fatalf("Error with searching expectedTable in metadata: %s\n%s", expectedTable.Name, err)
}
if !elementsMatch(expectedTable, metadataTableColumns) {
t.Errorf(
"Table columns do not match: %s\nexpected: %s\nactual: %s",
expectedTable.Name,
expectedTable.Columns,
metadataTableColumns,
)
}
}
}
func elementsMatch(expectedTable ExpectedTable, metadataTable Columns) bool {
if len(expectedTable.Columns) != len(metadataTable) {
return false
}
hasuraColumns := make(map[string]struct{})
for _, columnName := range metadataTable {
hasuraColumns[columnName] = struct{}{}
}
for _, expectedColumn := range expectedTable.Columns {
if _, ok := hasuraColumns[expectedColumn]; !ok {
return false
}
}
return true
}
func getTableColumns(metadata Metadata, tableName string, sourceName string, role string) (Columns, error) {
for _, source := range metadata.Sources {
if source.Name != sourceName {
continue
}
for _, table := range source.Tables {
if table.Schema.Name != tableName {
continue
}
for _, selectPermission := range table.SelectPermissions {
if selectPermission.Role == role {
return selectPermission.Permission.Columns, nil
}
}
}
}
return nil, errors.Errorf("Table %s for role %s was not found", tableName, role)
}
func parseExpectedMetadata(filename string) (*ExpectedMetadata, error) {
buf, err := readFile(filename)
if err != nil {
return nil, err
}
var output ExpectedMetadata
if err := yaml.NewDecoder(buf).Decode(&output); err != nil {
return nil, err
}
return &output, nil
}
func readFile(filename string) (*bytes.Buffer, error) {
if filename == "" {
return nil, errors.Errorf("you have to provide configuration filename")
}
data, err := os.ReadFile(filename)
if err != nil {
return nil, errors.Wrapf(err, "reading file %s", filename)
}
return bytes.NewBuffer(data), nil
}