1 package ordering
2
3 import (
4 "testing"
5
6 "google.golang.org/genproto/googleapis/example/library/v1"
7 "google.golang.org/protobuf/proto"
8 "gotest.tools/v3/assert"
9 )
10
11 func TestOrderBy_UnmarshalString(t *testing.T) {
12 t.Parallel()
13 for _, tt := range []struct {
14 orderBy string
15 expected OrderBy
16 errorContains string
17 }{
18 {
19 orderBy: "",
20 expected: OrderBy{},
21 },
22
23 {
24 orderBy: "foo desc, bar",
25 expected: OrderBy{
26 Fields: []Field{
27 {Path: "foo", Desc: true},
28 {Path: "bar"},
29 },
30 },
31 },
32
33 {
34 orderBy: "foo.bar",
35 expected: OrderBy{
36 Fields: []Field{
37 {Path: "foo.bar"},
38 },
39 },
40 },
41
42 {
43 orderBy: " foo , bar desc ",
44 expected: OrderBy{
45 Fields: []Field{
46 {Path: "foo"},
47 {Path: "bar", Desc: true},
48 },
49 },
50 },
51
52 {orderBy: "foo,", errorContains: "invalid format"},
53 {orderBy: ",", errorContains: "invalid "},
54 {orderBy: ",foo", errorContains: "invalid format"},
55 {orderBy: "foo/bar", errorContains: "invalid character '/'"},
56 {orderBy: "foo bar", errorContains: "invalid format"},
57 } {
58 tt := tt
59 t.Run(tt.orderBy, func(t *testing.T) {
60 t.Parallel()
61 var actual OrderBy
62 err := actual.UnmarshalString(tt.orderBy)
63 if tt.errorContains != "" {
64 assert.ErrorContains(t, err, tt.errorContains)
65 } else {
66 assert.NilError(t, err)
67 assert.DeepEqual(t, tt.expected, actual)
68 }
69 })
70 }
71 }
72
73 func TestOrderBy_ValidateForPaths(t *testing.T) {
74 t.Parallel()
75 for _, tt := range []struct {
76 name string
77 orderBy OrderBy
78 paths []string
79 errorContains string
80 }{
81 {
82 name: "valid empty",
83 orderBy: OrderBy{},
84 paths: []string{},
85 },
86
87 {
88 name: "valid single",
89 orderBy: OrderBy{
90 Fields: []Field{
91 {Path: "name"},
92 {Path: "author"},
93 },
94 },
95 paths: []string{"name", "author", "read"},
96 },
97
98 {
99 name: "invalid single",
100 orderBy: OrderBy{
101 Fields: []Field{
102 {Path: "name"},
103 {Path: "foo"},
104 },
105 },
106 paths: []string{"name", "author", "read"},
107 errorContains: "invalid field path: foo",
108 },
109
110 {
111 name: "valid nested",
112 orderBy: OrderBy{
113 Fields: []Field{
114 {Path: "name"},
115 {Path: "book.name"},
116 },
117 },
118 paths: []string{"name", "book.name", "book.author", "book.read"},
119 },
120
121 {
122 name: "invalid nested",
123 orderBy: OrderBy{
124 Fields: []Field{
125 {Path: "name"},
126 {Path: "book.foo"},
127 },
128 },
129 paths: []string{"name", "book.name", "book.author", "book.read"},
130 errorContains: "invalid field path: book.foo",
131 },
132 } {
133 tt := tt
134 t.Run(tt.name, func(t *testing.T) {
135 t.Parallel()
136 if tt.errorContains != "" {
137 assert.ErrorContains(t, tt.orderBy.ValidateForPaths(tt.paths...), tt.errorContains)
138 } else {
139 assert.NilError(t, tt.orderBy.ValidateForPaths(tt.paths...))
140 }
141 })
142 }
143 }
144
145 func TestOrderBy_ValidateForMessage(t *testing.T) {
146 t.Parallel()
147 for _, tt := range []struct {
148 name string
149 orderBy OrderBy
150 message proto.Message
151 errorContains string
152 }{
153 {
154 name: "valid empty",
155 orderBy: OrderBy{},
156 message: &library.Book{},
157 },
158
159 {
160 name: "valid single",
161 orderBy: OrderBy{
162 Fields: []Field{
163 {Path: "name"},
164 {Path: "author"},
165 },
166 },
167 message: &library.Book{},
168 },
169
170 {
171 name: "invalid single",
172 orderBy: OrderBy{
173 Fields: []Field{
174 {Path: "name"},
175 {Path: "foo"},
176 },
177 },
178 message: &library.Book{},
179 errorContains: "invalid field path: foo",
180 },
181
182 {
183 name: "valid nested",
184 orderBy: OrderBy{
185 Fields: []Field{
186 {Path: "parent"},
187 {Path: "book.name"},
188 },
189 },
190 message: &library.CreateBookRequest{},
191 },
192
193 {
194 name: "invalid nested",
195 orderBy: OrderBy{
196 Fields: []Field{
197 {Path: "parent"},
198 {Path: "book.foo"},
199 },
200 },
201 message: &library.CreateBookRequest{},
202 errorContains: "invalid field path: book.foo",
203 },
204 } {
205 tt := tt
206 t.Run(tt.name, func(t *testing.T) {
207 t.Parallel()
208 if tt.errorContains != "" {
209 assert.ErrorContains(t, tt.orderBy.ValidateForMessage(tt.message), tt.errorContains)
210 } else {
211 assert.NilError(t, tt.orderBy.ValidateForMessage(tt.message))
212 }
213 })
214 }
215 }
216
217 func TestField_SubFields(t *testing.T) {
218 t.Parallel()
219 for _, tt := range []struct {
220 name string
221 field Field
222 expected []string
223 }{
224 {
225 name: "empty",
226 field: Field{},
227 expected: nil,
228 },
229
230 {
231 name: "single",
232 field: Field{Path: "foo"},
233 expected: []string{"foo"},
234 },
235
236 {
237 name: "multiple",
238 field: Field{Path: "foo.bar"},
239 expected: []string{"foo", "bar"},
240 },
241 } {
242 tt := tt
243 t.Run(tt.name, func(t *testing.T) {
244 t.Parallel()
245 assert.DeepEqual(t, tt.expected, tt.field.SubFields())
246 })
247 }
248 }
249
View as plain text