-
Notifications
You must be signed in to change notification settings - Fork 2
/
clone_test.go
135 lines (114 loc) · 3.5 KB
/
clone_test.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
134
135
package datapasta_test
import (
"context"
"fmt"
"testing"
"github.com/ProlificLabs/datapasta"
"github.com/stretchr/testify/assert"
)
func TestDownloadUpload(t *testing.T) {
db, assert := testDB{T: t}, assert.New(t)
res, _, err := datapasta.Download(context.Background(), db, "company", "id", 10)
assert.NoError(err)
t.Log(res)
assert.Equal(10, res[0]["id"])
assert.Equal("produces socks", res[1]["desc"])
assert.Equal("socks", res[2]["name"])
assert.Equal("socks are cool", res[3]["detail"])
// users are expected to do some cleanup, so test that it works
for _, row := range res {
cleanup(row)
}
assert.NoError(datapasta.Upload(context.Background(), db, res))
assert.Equal(11, res[0]["id"])
assert.Equal(12, res[1]["id"])
assert.Equal(13, res[2]["id"])
assert.Equal(11, res[3]["company_id"])
}
func cleanup(row map[string]any) {
if row[datapasta.DumpTableKey] == "company" {
row["api_key"] = "obfuscated"
}
}
type testDB struct{ *testing.T }
// return unseen records
func (d testDB) SelectMatchingRows(tname string, conds map[string][]any) ([]map[string]any, error) {
d.Logf("SELECT FROM %s WHERE %#v", tname, conds)
switch tname {
case "company":
if conds["id"][0] == 10 {
return []map[string]any{{"id": 10, "api_key": "secret_api_key"}}, nil
}
case "product":
if conds["factory_id"] != nil {
// we revisit this table because its a dependency of factory as well
return nil, nil
}
if conds["company_id"][0] == 10 {
return []map[string]any{{"id": 5, "name": "socks", "company_id": 10, "factory_id": 23}}, nil
}
case "factory":
if conds["id"][0] == 23 {
return []map[string]any{{"id": 23, "desc": "produces socks"}}, nil
}
case "company_details":
if conds["company_id"][0] == 10 {
return []map[string]any{{"company_id": 10, "detail": "socks are cool"}}, nil
}
}
return nil, fmt.Errorf("no mock for %s where %#v", tname, conds)
}
func (d testDB) PrimaryKeys() map[string]string {
return nil
}
func (d testDB) InsertRecord(map[string]any) (any, error) { return nil, nil }
// apply the updates from the cols to the row
func (d testDB) Update(id datapasta.RecordID, cols map[string]any) error { return nil }
// delete the row
func (d testDB) Delete(id datapasta.RecordID) error { return nil }
func (d testDB) Mapping() ([]datapasta.Mapping, error) { return nil, nil }
// upload a batch of records
func (d testDB) Insert(records ...map[string]any) error {
for _, m := range records {
d.Logf("inserting %#v", m)
if m[datapasta.DumpTableKey] == "company" && m["id"] == 10 {
if m["api_key"] != "obfuscated" {
d.Errorf("didn't obfuscated company 9's api key, got %s", m["api_key"])
}
m["id"] = 11
continue
}
if m[datapasta.DumpTableKey] == "factory" && m["id"] == 23 {
m["id"] = 12
continue
}
if m[datapasta.DumpTableKey] == "product" && m["id"] == 5 {
m["id"] = 13
continue
}
if m[datapasta.DumpTableKey] == "company_details" && m["company_id"] == 10 {
m["company_id"] = 11
continue
}
return fmt.Errorf("unexpected insert: %#v", m)
}
return nil
}
// get foriegn key mapping
func (d testDB) ForeignKeys() []datapasta.ForeignKey {
return []datapasta.ForeignKey{
{
BaseTable: "company", BaseCol: "id",
ReferencingTable: "product", ReferencingCol: "company_id",
},
{
BaseTable: "factory", BaseCol: "id",
ReferencingTable: "product", ReferencingCol: "factory_id",
},
{
BaseTable: "company", BaseCol: "id",
ReferencingTable: "company_details", ReferencingCol: "company_id",
},
}
}
var _ datapasta.Database = testDB{}