github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/pkg/couchdb/stream/all_docs_test.go (about) 1 package stream 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "strings" 7 "testing" 8 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/require" 11 ) 12 13 const input = ` 14 { 15 "total_rows": 6, 16 "offset": 0, 17 "rows": [ 18 { 19 "id": "1bbde1890ad23cb023e0b2ee1d0cc1aa", 20 "key": "1bbde1890ad23cb023e0b2ee1d0cc1aa", 21 "value": { 22 "rev": "1-14532ac999e880c2b731f0bd6ed5aef5" 23 }, 24 "doc": { 25 "_id": "1bbde1890ad23cb023e0b2ee1d0cc1aa", 26 "_rev": "1-14532ac999e880c2b731f0bd6ed5aef5", 27 "type": "file", 28 "name": "happycloud.png", 29 "dir_id": "ecbc071979a81554709a0394310c5291", 30 "created_at": "2022-01-03T16:07:37.886Z", 31 "updated_at": "2022-01-03T16:07:37.886Z", 32 "size": "5167", 33 "md5sum": "+ifa4cMPFbvDY8hERyfyGw==", 34 "mime": "image/png", 35 "class": "image", 36 "executable": false, 37 "trashed": false, 38 "encrypted": false, 39 "metadata": { 40 "arrays": [[ 41 [{ "foo": "bar", "more": [] }], 42 [{ "foo": "baz", "more": [] }] 43 ]], 44 "datetime": "2022-01-03T16:07:37.886Z", 45 "extractor_version": 2, 46 "height": 84, 47 "width": 110 48 }, 49 "cozyMetadata": { 50 "doctypeVersion": "1", 51 "metadataVersion": 1, 52 "createdAt": "2022-10-24T17:32:27.187580797+02:00", 53 "createdByApp": "drive", 54 "updatedAt": "2022-10-24T17:32:27.187580797+02:00", 55 "updatedByApps": [ 56 { 57 "slug": "drive", 58 "date": "2022-10-24T17:32:27.187580797+02:00", 59 "instance": "http://joe.localhost:8080/" 60 } 61 ], 62 "createdOn": "http://joe.localhost:8080/", 63 "uploadedAt": "2022-10-24T17:32:27.187580797+02:00", 64 "uploadedBy": { 65 "slug": "drive" 66 }, 67 "uploadedOn": "http://joe.localhost:8080/" 68 } 69 } 70 }, 71 { 72 "id": "_design/disk-usage", 73 "key": "_design/disk-usage", 74 "value": { 75 "rev": "1-aa2ea41ec37738d50438e5b87fa5f544" 76 }, 77 "doc": { 78 "_id": "_design/disk-usage", 79 "_rev": "1-aa2ea41ec37738d50438e5b87fa5f544", 80 "language": "javascript", 81 "views": { 82 "disk-usage": { 83 "map": "function(doc) { if (doc.type === 'file') { emit(doc.dir_id, +doc.size); } }", 84 "reduce": "_sum" 85 } 86 } 87 } 88 }, 89 { 90 "id": "_design/by-dir-id-updated-at", 91 "key": "_design/by-dir-id-updated-at", 92 "value": { 93 "rev": "1-afade1d0263e3fb50ab52b61445aa4b9" 94 }, 95 "doc": { 96 "_id": "_design/by-dir-id-updated-at", 97 "_rev": "1-afade1d0263e3fb50ab52b61445aa4b9", 98 "language": "query", 99 "views": { 100 "5a9b035bcbceb460f09d8ae4f4ebf60ffa37125e": { 101 "map": { 102 "fields": { 103 "dir_id": "asc", 104 "updated_at": "asc" 105 }, 106 "partial_filter_selector": {} 107 }, 108 "reduce": "_count", 109 "options": { 110 "def": { 111 "fields": [ 112 "dir_id", 113 "updated_at" 114 ] 115 } 116 } 117 } 118 } 119 } 120 }, 121 { 122 "id": "ecbc071979a81554709a0394310c5291", 123 "key": "ecbc071979a81554709a0394310c5291", 124 "value": { 125 "rev": "1-b894889f9135ca4ba915d6e7e96fba08" 126 }, 127 "doc": { 128 "_id": "ecbc071979a81554709a0394310c5291", 129 "_rev": "1-b894889f9135ca4ba915d6e7e96fba08", 130 "type": "directory", 131 "name": "Photos", 132 "dir_id": "io.cozy.files.root-dir", 133 "created_at": "2022-09-19T13:45:54.565507012+02:00", 134 "updated_at": "2022-09-19T13:45:54.565507012+02:00", 135 "path": "/Photos", 136 "cozyMetadata": { 137 "doctypeVersion": "1", 138 "metadataVersion": 1, 139 "createdAt": "2022-09-19T13:45:54.565507834+02:00", 140 "updatedAt": "2022-09-19T13:45:54.565507834+02:00", 141 "createdOn": "http://joe.localhost:8080/" 142 } 143 } 144 }, 145 { 146 "id": "io.cozy.files.root-dir", 147 "key": "io.cozy.files.root-dir", 148 "value": { 149 "rev": "1-1e0b279e7a36ccc415c1843f0355840f" 150 }, 151 "doc": { 152 "_id": "io.cozy.files.root-dir", 153 "_rev": "1-1e0b279e7a36ccc415c1843f0355840f", 154 "type": "directory", 155 "created_at": "2022-09-19T13:45:54.54955097+02:00", 156 "updated_at": "2022-09-19T13:45:54.54955097+02:00", 157 "path": "/" 158 } 159 }, 160 { 161 "id": "io.cozy.files.trash-dir", 162 "key": "io.cozy.files.trash-dir", 163 "value": { 164 "rev": "1-11f72bef9b00c46cf8fe3c35c20bd86e" 165 }, 166 "doc": { 167 "_id": "io.cozy.files.trash-dir", 168 "_rev": "1-11f72bef9b00c46cf8fe3c35c20bd86e", 169 "type": "directory", 170 "name": ".cozy_trash", 171 "dir_id": "io.cozy.files.root-dir", 172 "created_at": "2022-09-19T13:45:54.54955097+02:00", 173 "updated_at": "2022-09-19T13:45:54.54955097+02:00", 174 "path": "/.cozy_trash" 175 } 176 } 177 ] 178 }` 179 180 func TestSkipDesingDocs(t *testing.T) { 181 filter := NewAllDocsFilter(nil) 182 filter.SkipDesignDocs() 183 var w bytes.Buffer 184 require.NoError(t, filter.Stream(strings.NewReader(input), &w)) 185 var data map[string]interface{} 186 require.NoError(t, json.Unmarshal(w.Bytes(), &data)) 187 assert.EqualValues(t, 0, data["offset"]) 188 assert.EqualValues(t, 4, data["total_rows"]) 189 rows, ok := data["rows"].([]interface{}) 190 require.True(t, ok) 191 assert.Len(t, rows, 4) 192 for i := range rows { 193 row, ok := rows[i].(map[string]interface{}) 194 require.True(t, ok) 195 id, ok := row["id"].(string) 196 require.True(t, ok) 197 assert.False(t, strings.HasPrefix(id, "_design/")) 198 key, ok := row["key"].(string) 199 require.True(t, ok) 200 assert.Equal(t, id, key) 201 value, ok := row["value"].(map[string]interface{}) 202 require.True(t, ok) 203 assert.Contains(t, value["rev"], "1-") 204 } 205 } 206 207 func TestFilterBasicFields(t *testing.T) { 208 filter := NewAllDocsFilter([]string{"_id", "type", "path"}) 209 var w bytes.Buffer 210 require.NoError(t, filter.Stream(strings.NewReader(input), &w)) 211 var data map[string]interface{} 212 require.NoError(t, json.Unmarshal(w.Bytes(), &data)) 213 assert.EqualValues(t, 0, data["offset"]) 214 assert.EqualValues(t, 6, data["total_rows"]) 215 rows, ok := data["rows"].([]interface{}) 216 require.True(t, ok) 217 assert.Len(t, rows, 6) 218 219 row, ok := rows[4].(map[string]interface{}) 220 require.True(t, ok) 221 assert.Equal(t, "io.cozy.files.root-dir", row["id"]) 222 assert.NotContains(t, row, "key") 223 assert.NotContains(t, row, "value") 224 doc, ok := row["doc"].(map[string]interface{}) 225 require.True(t, ok) 226 assert.Equal(t, "io.cozy.files.root-dir", doc["_id"]) 227 assert.Equal(t, "directory", doc["type"]) 228 assert.Equal(t, "/", doc["path"]) 229 assert.NotContains(t, doc, "_rev") 230 assert.NotContains(t, doc, "name") 231 assert.NotContains(t, doc, "dir_id") 232 assert.NotContains(t, doc, "created_at") 233 assert.NotContains(t, doc, "updated_at") 234 235 row, ok = rows[5].(map[string]interface{}) 236 require.True(t, ok) 237 assert.Equal(t, "io.cozy.files.trash-dir", row["id"]) 238 assert.NotContains(t, row, "key") 239 assert.NotContains(t, row, "value") 240 doc, ok = row["doc"].(map[string]interface{}) 241 require.True(t, ok) 242 assert.Equal(t, "io.cozy.files.trash-dir", doc["_id"]) 243 assert.Equal(t, "directory", doc["type"]) 244 assert.Equal(t, "/.cozy_trash", doc["path"]) 245 assert.NotContains(t, doc, "_rev") 246 assert.NotContains(t, doc, "name") 247 assert.NotContains(t, doc, "dir_id") 248 assert.NotContains(t, doc, "created_at") 249 assert.NotContains(t, doc, "updated_at") 250 } 251 252 func TestFilterDottedFields(t *testing.T) { 253 filter := NewAllDocsFilter([]string{"metadata.datetime", "cozyMetadata.uploadedBy"}) 254 var w bytes.Buffer 255 require.NoError(t, filter.Stream(strings.NewReader(input), &w)) 256 var data map[string]interface{} 257 require.NoError(t, json.Unmarshal(w.Bytes(), &data)) 258 assert.EqualValues(t, 0, data["offset"]) 259 assert.EqualValues(t, 6, data["total_rows"]) 260 rows, ok := data["rows"].([]interface{}) 261 require.True(t, ok) 262 assert.Len(t, rows, 6) 263 264 row, ok := rows[0].(map[string]interface{}) 265 require.True(t, ok) 266 assert.Equal(t, "1bbde1890ad23cb023e0b2ee1d0cc1aa", row["id"]) 267 doc, ok := row["doc"].(map[string]interface{}) 268 require.True(t, ok) 269 assert.NotContains(t, doc, "_id") 270 assert.NotContains(t, doc, "_rev") 271 assert.NotContains(t, doc, "name") 272 assert.NotContains(t, doc, "dir_id") 273 assert.NotContains(t, doc, "created_at") 274 assert.NotContains(t, doc, "updated_at") 275 metadata, ok := doc["metadata"].(map[string]interface{}) 276 require.True(t, ok) 277 assert.Equal(t, "2022-01-03T16:07:37.886Z", metadata["datetime"]) 278 assert.NotContains(t, metadata, "extractor_version") 279 assert.NotContains(t, metadata, "height") 280 assert.NotContains(t, metadata, "width") 281 cozyMetadata, ok := doc["cozyMetadata"].(map[string]interface{}) 282 require.True(t, ok) 283 assert.Equal(t, "2022-01-03T16:07:37.886Z", metadata["datetime"]) 284 assert.NotContains(t, cozyMetadata, "doctypeVersion") 285 assert.NotContains(t, cozyMetadata, "uploadedAt") 286 assert.NotContains(t, cozyMetadata, "uploadedOn") 287 uploadedBy, ok := cozyMetadata["uploadedBy"].(map[string]interface{}) 288 require.True(t, ok) 289 assert.Equal(t, "drive", uploadedBy["slug"]) 290 }