1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package test
17
18 import (
19 "net/http"
20 "net/url"
21 "os"
22 "runtime"
23 "strings"
24 "testing"
25
26 "github.com/gopherjs/gopherjs/js"
27
28 kivik "github.com/go-kivik/kivik/v4"
29 "github.com/go-kivik/kivik/v4/kiviktest"
30 "github.com/go-kivik/kivik/v4/kiviktest/kt"
31 )
32
33 func init() {
34 if pouchDB := js.Global.Get("PouchDB"); pouchDB != js.Undefined {
35 memPouch := js.Global.Get("PouchDB").Call("defaults", map[string]interface{}{
36 "db": js.Global.Call("require", "memdown"),
37 })
38 js.Global.Set("PouchDB", memPouch)
39 }
40 }
41
42
43 func RegisterPouchDBSuites() {
44 kiviktest.RegisterSuite(kiviktest.SuitePouchLocal, kt.SuiteConfig{
45 "PreCleanup.skip": true,
46
47
48 "Log.skip": true,
49 "Flush.skip": true,
50 "Security.skip": true,
51 "SetSecurity.skip": true,
52 "DBUpdates.skip": true,
53
54 "AllDBs.skip": true,
55 "CreateDB.skip": true,
56 "DBExists.skip": true,
57
58 "AllDocs/Admin.databases": []string{},
59 "AllDocs/RW/group/Admin/WithDocs/UpdateSeq.skip": true,
60
61 "Find/Admin.databases": []string{},
62
63
64
65 "Explain.databases": []string{},
66 "Explain.plan": &kivik.QueryPlan{
67 Index: map[string]interface{}{
68 "ddoc": nil,
69 "name": "_all_docs",
70 "type": "special",
71 "def": map[string]interface{}{"fields": []interface{}{map[string]string{"_id": "asc"}}},
72 },
73 Selector: map[string]interface{}{"_id": map[string]interface{}{"$gt": nil}},
74 Options: map[string]interface{}{
75 "bookmark": "nil",
76 "conflicts": false,
77 "r": []int{49},
78 "sort": map[string]interface{}{},
79 "use_index": []interface{}{},
80 },
81 Fields: func() []interface{} {
82 if ver := runtime.Version(); strings.HasPrefix(ver, "go1.16") {
83 return []interface{}{}
84 }
85
86 return nil
87 }(),
88 Range: map[string]interface{}{
89 "start_key": nil,
90 },
91 },
92
93 "Query/RW/group/Admin/WithDocs/UpdateSeq.skip": true,
94
95 "Version.version": `^[789]\.\d\.\d$`,
96 "Version.vendor": `^PouchDB$`,
97 "Version.vendor_version": `^[789]\.\d\.\d$`,
98
99 "Get/RW/group/Admin/bogus.status": http.StatusNotFound,
100 "Get/RW/group/NoAuth/bogus.status": http.StatusNotFound,
101
102 "GetRev/RW/group/Admin/bogus.status": http.StatusNotFound,
103 "GetRev/RW/group/NoAuth/bogus.status": http.StatusNotFound,
104
105 "Delete/RW/Admin/group/MissingDoc.status": http.StatusNotFound,
106 "Delete/RW/Admin/group/InvalidRevFormat.status": http.StatusBadRequest,
107 "Delete/RW/Admin/group/WrongRev.status": http.StatusConflict,
108
109 "Stats/Admin.skip": true,
110
111 "BulkDocs/RW/Admin/group/Mix/Conflict.status": http.StatusConflict,
112
113 "GetAttachment/RW/group/Admin/foo/NotFound.status": http.StatusNotFound,
114
115 "GetAttachmentMeta/RW/group/Admin/foo/NotFound.status": http.StatusNotFound,
116
117 "PutAttachment/RW/group/Admin/Conflict.status": http.StatusConflict,
118
119
120 "DeleteAttachment/RW/group/Admin/NoDoc.status": http.StatusNotFound,
121
122 "Put/RW/Admin/group/LeadingUnderscoreInID.status": http.StatusBadRequest,
123 "Put/RW/Admin/group/Conflict.status": http.StatusConflict,
124
125 "CreateIndex/RW/Admin/group/EmptyIndex.status": http.StatusInternalServerError,
126 "CreateIndex/RW/Admin/group/BlankIndex.status": http.StatusBadRequest,
127 "CreateIndex/RW/Admin/group/InvalidIndex.status": http.StatusInternalServerError,
128 "CreateIndex/RW/Admin/group/NilIndex.status": http.StatusInternalServerError,
129 "CreateIndex/RW/Admin/group/InvalidJSON.status": http.StatusBadRequest,
130
131 "GetIndexes.databases": []string{},
132
133 "DeleteIndex/RW/Admin/group/NotFoundDdoc.status": http.StatusNotFound,
134 "DeleteIndex/RW/Admin/group/NotFoundName.status": http.StatusNotFound,
135
136 "Replicate.skip": true,
137
138 "Query/RW/group/Admin/WithoutDocs/ScanDoc.status": http.StatusBadRequest,
139
140 "Changes/Continuous.options": kivik.Params(map[string]interface{}{
141 "live": true,
142 "timeout": false,
143 }),
144 })
145 kiviktest.RegisterSuite(kiviktest.SuitePouchRemote, kt.SuiteConfig{
146
147 "Log.skip": true,
148 "Flush.skip": true,
149 "Session.skip": true,
150 "Security.skip": true,
151 "SetSecurity.skip": true,
152 "DBUpdates.skip": true,
153
154 "PreCleanup.skip": true,
155
156 "AllDBs.skip": true,
157
158 "CreateDB/RW/NoAuth.status": http.StatusUnauthorized,
159 "CreateDB/RW/Admin/Recreate.status": http.StatusPreconditionFailed,
160
161 "DBExists.databases": []string{"_users", "chicken"},
162 "DBExists/Admin/_users.exists": true,
163 "DBExists/Admin/chicken.exists": false,
164 "DBExists/NoAuth/_users.exists": true,
165 "DBExists/NoAuth/chicken.exists": false,
166 "DBExists/RW/group/Admin.exists": true,
167 "DBExists/RW/group/NoAuth.exists": true,
168
169 "DestroyDB/RW/NoAuth/NonExistantDB.status": http.StatusNotFound,
170 "DestroyDB/RW/Admin/NonExistantDB.status": http.StatusNotFound,
171 "DestroyDB/RW/NoAuth/ExistingDB.status": http.StatusUnauthorized,
172
173 "AllDocs.databases": []string{"_replicator", "_users", "chicken"},
174 "AllDocs/Admin/_replicator.expected": []string{"_design/_replicator"},
175 "AllDocs/Admin/_replicator.offset": 0,
176 "AllDocs/Admin/_users.expected": []string{"_design/_auth"},
177 "AllDocs/Admin/chicken.status": http.StatusNotFound,
178 "AllDocs/NoAuth/_replicator.status": http.StatusUnauthorized,
179 "AllDocs/NoAuth/_users.status": http.StatusUnauthorized,
180 "AllDocs/NoAuth/chicken.status": http.StatusNotFound,
181 "AllDocs/Admin/_replicator/WithDocs/UpdateSeq.skip": true,
182 "AllDocs/Admin/_users/WithDocs/UpdateSeq.skip": true,
183 "AllDocs/RW/group/Admin/WithDocs/UpdateSeq.skip": true,
184 "AllDocs/RW/group/Admin/WithoutDocs/UpdateSeq.skip": true,
185 "AllDocs/RW/group/NoAuth/WithDocs/UpdateSeq.skip": true,
186 "AllDocs/RW/group/NoAuth/WithoutDocs/UpdateSeq.skip": true,
187
188 "Find.databases": []string{"chicken", "_duck"},
189 "Find/Admin/chicken.status": http.StatusNotFound,
190 "Find/Admin/_duck.status": http.StatusNotFound,
191 "Find/NoAuth/chicken.status": http.StatusNotFound,
192 "Find/NoAuth/_duck.status": http.StatusUnauthorized,
193
194
195 "Find/RW/group/NoAuth/Warning.warning": "No matching index found, create an index to optimize query time",
196
197 "Explain.databases": []string{"chicken", "_duck"},
198 "Explain/Admin/chicken.status": http.StatusNotFound,
199 "Explain/Admin/_duck.status": http.StatusNotFound,
200 "Explain/NoAuth/chicken.status": http.StatusNotFound,
201 "Explain/NoAuth/_duck.status": http.StatusUnauthorized,
202 "Explain.plan": &kivik.QueryPlan{
203 Index: map[string]interface{}{
204 "ddoc": nil,
205 "name": "_all_docs",
206 "type": "special",
207 "def": map[string]interface{}{"fields": []interface{}{map[string]string{"_id": "asc"}}},
208 },
209 Selector: map[string]interface{}{"_id": map[string]interface{}{"$gt": nil}},
210 Options: map[string]interface{}{
211 "bookmark": "nil",
212 "conflicts": false,
213 "execution_stats": false,
214 "r": []int{49},
215 "sort": map[string]interface{}{},
216 "use_index": []interface{}{},
217 "stable": false,
218 "stale": false,
219 "update": true,
220 "skip": 0,
221 "limit": 25,
222 "fields": "all_fields",
223 },
224 Fields: func() []interface{} {
225 if ver := runtime.Version(); strings.HasPrefix(ver, "go1.16") {
226 return []interface{}{}
227 }
228
229 return nil
230 }(),
231 Range: nil,
232 Limit: 25,
233 },
234
235 "CreateIndex/RW/Admin/group/EmptyIndex.status": http.StatusBadRequest,
236 "CreateIndex/RW/Admin/group/BlankIndex.status": http.StatusBadRequest,
237 "CreateIndex/RW/Admin/group/InvalidIndex.status": http.StatusBadRequest,
238 "CreateIndex/RW/Admin/group/NilIndex.status": http.StatusBadRequest,
239 "CreateIndex/RW/Admin/group/InvalidJSON.status": http.StatusBadRequest,
240 "CreateIndex/RW/NoAuth/group/EmptyIndex.status": http.StatusBadRequest,
241 "CreateIndex/RW/NoAuth/group/BlankIndex.status": http.StatusBadRequest,
242 "CreateIndex/RW/NoAuth/group/InvalidIndex.status": http.StatusBadRequest,
243 "CreateIndex/RW/NoAuth/group/NilIndex.status": http.StatusBadRequest,
244 "CreateIndex/RW/NoAuth/group/InvalidJSON.status": http.StatusBadRequest,
245 "CreateIndex/RW/NoAuth/group/Valid.status": http.StatusInternalServerError,
246
247 "GetIndexes.databases": []string{"_replicator", "_users", "_global_changes"},
248 "GetIndexes/Admin/_replicator.indexes": []kivik.Index{kt.AllDocsIndex},
249 "GetIndexes/Admin/_users.indexes": []kivik.Index{kt.AllDocsIndex},
250 "GetIndexes/Admin/_global_changes.indexes": []kivik.Index{kt.AllDocsIndex},
251 "GetIndexes/NoAuth/_replicator.indexes": []kivik.Index{kt.AllDocsIndex},
252 "GetIndexes/NoAuth/_users.indexes": []kivik.Index{kt.AllDocsIndex},
253 "GetIndexes/NoAuth/_global_changes.skip": true,
254 "GetIndexes/NoAuth/_global_changes.status": http.StatusUnauthorized,
255 "GetIndexes/RW.indexes": []kivik.Index{
256 kt.AllDocsIndex,
257 {
258 DesignDoc: "_design/foo",
259 Name: "bar",
260 Type: "json",
261 Definition: map[string]interface{}{
262 "fields": []map[string]string{
263 {"foo": "asc"},
264 },
265 "partial_filter_selector": map[string]string{},
266 },
267 },
268 },
269
270 "DeleteIndex/RW/Admin/group/NotFoundDdoc.status": http.StatusNotFound,
271 "DeleteIndex/RW/Admin/group/NotFoundName.status": http.StatusNotFound,
272 "DeleteIndex/RW/NoAuth/group/NotFoundDdoc.status": http.StatusNotFound,
273 "DeleteIndex/RW/NoAuth/group/NotFoundName.status": http.StatusNotFound,
274
275 "Query/RW/group/Admin/WithDocs/UpdateSeq.skip": true,
276 "Query/RW/group/NoAuth/WithDocs/UpdateSeq.skip": true,
277
278 "Version.version": `^[789]\.\d\.\d$`,
279 "Version.vendor": `^PouchDB$`,
280 "Version.vendor_version": `^[789]\.\d\.\d$`,
281
282 "Get/RW/group/Admin/bogus.status": http.StatusNotFound,
283 "Get/RW/group/NoAuth/bogus.status": http.StatusNotFound,
284
285 "GetRev/RW/group/Admin/bogus.status": http.StatusNotFound,
286 "GetRev/RW/group/NoAuth/bogus.status": http.StatusNotFound,
287
288 "Delete/RW/Admin/group/MissingDoc.status": http.StatusNotFound,
289 "Delete/RW/Admin/group/InvalidRevFormat.status": http.StatusBadRequest,
290 "Delete/RW/Admin/group/WrongRev.status": http.StatusConflict,
291 "Delete/RW/NoAuth/group/MissingDoc.status": http.StatusNotFound,
292 "Delete/RW/NoAuth/group/InvalidRevFormat.status": http.StatusBadRequest,
293 "Delete/RW/NoAuth/group/WrongRev.status": http.StatusConflict,
294 "Delete/RW/NoAuth/group/DesignDoc.status": http.StatusUnauthorized,
295
296 "Stats.databases": []string{"_users", "chicken"},
297 "Stats/Admin/chicken.status": http.StatusNotFound,
298 "Stats/NoAuth/chicken.status": http.StatusNotFound,
299
300 "BulkDocs/RW/NoAuth/group/Mix/Conflict.status": http.StatusConflict,
301 "BulkDocs/RW/Admin/group/Mix/Conflict.status": http.StatusConflict,
302
303 "GetAttachment/RW/group/Admin/foo/NotFound.status": http.StatusNotFound,
304 "GetAttachment/RW/group/NoAuth/foo/NotFound.status": http.StatusNotFound,
305
306 "GetAttachmentMeta/RW/group/Admin/foo/NotFound.status": http.StatusNotFound,
307 "GetAttachmentMeta/RW/group/NoAuth/foo/NotFound.status": http.StatusNotFound,
308
309 "PutAttachment/RW/group/Admin/Conflict.status": http.StatusConflict,
310 "PutAttachment/RW/group/NoAuth/Conflict.status": http.StatusConflict,
311 "PutAttachment/RW/group/NoAuth/UpdateDesignDoc.status": http.StatusUnauthorized,
312 "PutAttachment/RW/group/NoAuth/CreateDesignDoc.status": http.StatusUnauthorized,
313
314
315
316 "DeleteAttachment/RW/group/Admin/NoDoc.status": http.StatusConflict,
317 "DeleteAttachment/RW/group/NoAuth/NoDoc.status": http.StatusConflict,
318 "DeleteAttachment/RW/group/NoAuth/DesignDoc.status": http.StatusUnauthorized,
319
320 "Put/RW/Admin/group/LeadingUnderscoreInID.status": http.StatusBadRequest,
321 "Put/RW/Admin/group/Conflict.status": http.StatusConflict,
322 "Put/RW/NoAuth/group/DesignDoc.status": http.StatusUnauthorized,
323 "Put/RW/NoAuth/group/LeadingUnderscoreInID.status": http.StatusBadRequest,
324 "Put/RW/NoAuth/group/Conflict.status": http.StatusConflict,
325
326 "Replicate.NotFoundDB": func() string {
327 var dsn string
328 for _, env := range []string{
329 "KIVIK_TESt_DSN_COUCH22", "KIVIK_TEST_DSN_COUCH21",
330 "KIVIK_TEST_DSN_COUCH20", "KIVIK_TEST_DSN_COUCH16",
331 "KIVIK_TEST_DSN_CLOUDANT",
332 } {
333 dsn = os.Getenv(env)
334 if dsn != "" {
335 break
336 }
337 }
338 parsed, _ := url.Parse(dsn)
339 parsed.User = nil
340 return strings.TrimSuffix(parsed.String(), "/") + "/doesntexist"
341 }(),
342 "Replicate.prefix": "none",
343 "Replicate.timeoutSeconds": 5,
344 "Replicate.mode": "pouchdb",
345 "Replicate/RW/Admin/group/MissingSource/Results.status": http.StatusUnauthorized,
346 "Replicate/RW/Admin/group/MissingTarget/Results.status": http.StatusUnauthorized,
347 "Replicate/RW/NoAuth/group/MissingSource/Results.status": http.StatusUnauthorized,
348 "Replicate/RW/NoAuth/group/MissingTarget/Results.status": http.StatusUnauthorized,
349
350 "Query/RW/group/Admin/WithoutDocs/ScanDoc.status": http.StatusBadRequest,
351 "Query/RW/group/NoAuth/WithoutDocs/ScanDoc.status": http.StatusBadRequest,
352
353
354
355 "Changes/Continuous.options": kivik.Params(map[string]interface{}{
356 "live": true,
357 "timeout": false,
358 }),
359 })
360 }
361
362
363 func PouchLocalTest(t *testing.T) {
364 client, err := kivik.New("pouch", "")
365 if err != nil {
366 t.Errorf("Failed to connect to PouchDB driver: %s", err)
367 return
368 }
369 clients := &kt.Context{
370 RW: true,
371 Admin: client,
372 T: t,
373 }
374 kiviktest.RunTestsInternal(clients, kiviktest.SuitePouchLocal)
375 }
376
377
378 func PouchRemoteTest(t *testing.T) {
379 kiviktest.DoTest(t, kiviktest.SuitePouchRemote, "KIVIK_TEST_DSN_COUCH22")
380 }
381
View as plain text