1
16
17 package datapol
18
19 import (
20 "fmt"
21 "net/http"
22 "strings"
23 "testing"
24
25 "github.com/stretchr/testify/assert"
26 )
27
28 const (
29 marker = "hunter2"
30 )
31
32 type withDatapolTag struct {
33 Key string `json:"key" datapolicy:"password"`
34 }
35
36 type withExternalType struct {
37 Header http.Header `json:"header"`
38 }
39
40 type noDatapol struct {
41 Key string `json:"key"`
42 }
43
44 type datapolInMember struct {
45 secrets withDatapolTag
46 }
47
48 type datapolInSlice struct {
49 secrets []withDatapolTag
50 }
51
52 type datapolInMap struct {
53 secrets map[string]withDatapolTag
54 }
55
56 type datapolBehindPointer struct {
57 secrets *withDatapolTag
58 }
59
60 func TestValidate(t *testing.T) {
61 testcases := []struct {
62 name string
63 value interface{}
64 expect []string
65 badFilter bool
66 }{{
67 name: "Empty password",
68 value: withDatapolTag{},
69 expect: []string{},
70 }, {
71 name: "Non-empty password",
72 value: withDatapolTag{
73 Key: marker,
74 },
75 expect: []string{"password"},
76 }, {
77 name: "empty external type",
78 value: withExternalType{Header: http.Header{}},
79 expect: []string{},
80 }, {
81 name: "external type",
82 value: withExternalType{Header: http.Header{
83 "Authorization": []string{"Bearer hunter2"},
84 }},
85 expect: []string{"password", "token"},
86 }, {
87 name: "no datapol tag",
88 value: noDatapol{Key: marker},
89 expect: []string{},
90 badFilter: true,
91 }, {
92 name: "nested",
93 value: datapolInMember{
94 secrets: withDatapolTag{
95 Key: marker,
96 },
97 },
98 expect: []string{"password"},
99 }, {
100 name: "nested in pointer",
101 value: datapolBehindPointer{
102 secrets: &withDatapolTag{Key: marker},
103 },
104 expect: []string{},
105 }, {
106 name: "nested in slice",
107 value: datapolInSlice{
108 secrets: []withDatapolTag{{Key: marker}},
109 },
110 expect: []string{"password"},
111 }, {
112 name: "nested in map",
113 value: datapolInMap{
114 secrets: map[string]withDatapolTag{
115 "key": {Key: marker},
116 },
117 },
118 expect: []string{"password"},
119 }, {
120 name: "nested in map but empty",
121 value: datapolInMap{
122 secrets: map[string]withDatapolTag{
123 "key": {},
124 },
125 },
126 expect: []string{},
127 }, {
128 name: "struct in interface",
129 value: struct{ v interface{} }{v: withDatapolTag{
130 Key: marker,
131 }},
132 expect: []string{"password"},
133 }, {
134 name: "structptr in interface",
135 value: struct{ v interface{} }{v: &withDatapolTag{
136 Key: marker,
137 }},
138 expect: []string{},
139 }}
140 for _, tc := range testcases {
141 res := Verify(tc.value)
142 if !assert.ElementsMatch(t, tc.expect, res) {
143 t.Errorf("Wrong set of tags for %q. expect %v, got %v", tc.name, tc.expect, res)
144 }
145 if !tc.badFilter {
146 formatted := fmt.Sprintf("%v", tc.value)
147 if strings.Contains(formatted, marker) != (len(tc.expect) > 0) {
148 t.Errorf("Filter decision doesn't match formatted value for %q: tags: %v, format: %s", tc.name, tc.expect, formatted)
149 }
150 }
151 }
152 }
153
View as plain text