github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/web/data/not_synchronizing_test.go (about) 1 package data 2 3 import ( 4 "net/url" 5 "testing" 6 7 "github.com/cozy/cozy-stack/model/instance" 8 "github.com/cozy/cozy-stack/model/vfs" 9 "github.com/cozy/cozy-stack/pkg/config/config" 10 "github.com/cozy/cozy-stack/pkg/consts" 11 "github.com/cozy/cozy-stack/pkg/couchdb" 12 "github.com/cozy/cozy-stack/tests/testutils" 13 "github.com/gavv/httpexpect/v2" 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestNot(t *testing.T) { 19 if testing.Short() { 20 t.Skip("an instance is required for this test: test skipped due to the use of --short flag") 21 } 22 23 const Type = "io.cozy.events" 24 const ID = "4521C325F6478E45" 25 26 config.UseTestFile(t) 27 testutils.NeedCouchdb(t) 28 setup := testutils.NewSetup(t, t.Name()) 29 testInstance := setup.GetTestInstance() 30 scope := "io.cozy.doctypes io.cozy.files io.cozy.events " + 31 "io.cozy.anothertype io.cozy.nottype" 32 33 _, token := setup.GetTestClient(scope) 34 ts := setup.GetTestServer("/data", Routes) 35 t.Cleanup(ts.Close) 36 37 _ = couchdb.ResetDB(testInstance, Type) 38 _ = couchdb.CreateNamedDoc(testInstance, &couchdb.JSONDoc{ 39 Type: Type, 40 M: map[string]interface{}{ 41 "_id": ID, 42 "test": "testvalue", 43 }, 44 }) 45 46 t.Run("ListNotSynchronizingHandler", func(t *testing.T) { 47 e := testutils.CreateTestClient(t, ts.URL) 48 49 // Make doc 50 doc := getDocForTest(Type, testInstance) 51 52 // Make directories 53 makeNotSynchronzedOnTestDir(t, testInstance, doc, "test_not_sync_on_1") 54 makeNotSynchronzedOnTestDir(t, testInstance, doc, "test_not_sync_on_2") 55 makeNotSynchronzedOnTestDir(t, testInstance, doc, "test_not_sync_on_3") 56 makeNotSynchronzedOnTestDir(t, testInstance, doc, "test_not_sync_on_4") 57 58 // Simple query 59 obj := e.GET("/data/"+doc.DocType()+"/"+doc.ID()+"/relationships/not_synchronizing"). 60 WithHeader("Authorization", "Bearer "+token). 61 Expect().Status(200). 62 JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}). 63 Object() 64 65 obj.Path("$.meta.count").Equal(4) 66 obj.Value("links").Object().NotContainsKey("next") 67 obj.Value("data").Array().Length().Equal(4) 68 69 // Use the page limit 70 obj = e.GET("/data/"+doc.DocType()+"/"+doc.ID()+"/relationships/not_synchronizing"). 71 WithQuery("page[limit]", 3). 72 WithHeader("Authorization", "Bearer "+token). 73 Expect().Status(200). 74 JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}). 75 Object() 76 77 obj.Path("$.meta.count").Equal(4) 78 obj.Value("data").Array().Length().Equal(3) 79 rawNext := obj.Value("links").Object().Value("next").String().NotEmpty().Raw() 80 81 nextURL, err := url.Parse(rawNext) 82 require.NoError(t, err) 83 84 // Use the bookmark 85 obj = e.GET(nextURL.Path). 86 WithQueryString(nextURL.RawQuery). 87 WithHeader("Authorization", "Bearer "+token). 88 Expect().Status(200). 89 JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}). 90 Object() 91 92 obj.Value("data").Array().Length().Equal(1) 93 obj.Value("links").Object().NotContainsKey("next") 94 95 // Include the files 96 obj = e.GET("/data/"+doc.DocType()+"/"+doc.ID()+"/relationships/not_synchronizing"). 97 WithQuery("include", "files"). 98 WithHeader("Authorization", "Bearer "+token). 99 Expect().Status(200). 100 JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}). 101 Object() 102 103 obj.Value("included").Array().Length().Equal(4) 104 obj.Path("$.included[0].id").String().NotEmpty() 105 }) 106 107 t.Run("AddNotSynchronizing", func(t *testing.T) { 108 e := testutils.CreateTestClient(t, ts.URL) 109 110 // Make doc 111 doc := getDocForTest(Type, testInstance) 112 113 // Make dir 114 dir := makeNotSynchronzedOnTestDir(t, testInstance, nil, "test_not_sync_on") 115 116 // update it 117 e.POST("/data/"+doc.DocType()+"/"+doc.ID()+"/relationships/not_synchronizing"). 118 WithHeader("Authorization", "Bearer "+token). 119 WithHeader("Content-Type", "application/vnd.api+json"). 120 WithBytes([]byte(`{ 121 "data": { 122 "id": "` + dir.ID() + `", 123 "type": "` + dir.DocType() + `" 124 } 125 }`)). 126 Expect().Status(204) 127 128 dirdoc, err := testInstance.VFS().DirByID(dir.ID()) 129 assert.NoError(t, err) 130 assert.Len(t, dirdoc.NotSynchronizedOn, 1) 131 }) 132 133 t.Run("RemoveNotSynchronizing", func(t *testing.T) { 134 e := testutils.CreateTestClient(t, ts.URL) 135 136 // Make doc 137 doc := getDocForTest(Type, testInstance) 138 139 // Make directories 140 d6 := makeNotSynchronzedOnTestDir(t, testInstance, doc, "test_not_sync_on_6").ID() 141 d7 := makeNotSynchronzedOnTestDir(t, testInstance, doc, "test_not_sync_on_7").ID() 142 d8 := makeNotSynchronzedOnTestDir(t, testInstance, doc, "test_not_sync_on_8").ID() 143 d9 := makeNotSynchronzedOnTestDir(t, testInstance, doc, "test_not_sync_on_9").ID() 144 145 // update it 146 e.DELETE("/data/"+doc.DocType()+"/"+doc.ID()+"/relationships/not_synchronizing"). 147 WithHeader("Authorization", "Bearer "+token). 148 WithHeader("Content-Type", "application/vnd.api+json"). 149 WithBytes([]byte(`{ 150 "data": [ 151 {"id": "` + d8 + `", "type": "` + consts.Files + `"}, 152 {"id": "` + d6 + `", "type": "` + consts.Files + `"} 153 ] 154 }`)). 155 Expect().Status(204) 156 157 doc6, err := testInstance.VFS().DirByID(d6) 158 assert.NoError(t, err) 159 assert.Len(t, doc6.NotSynchronizedOn, 0) 160 doc8, err := testInstance.VFS().DirByID(d8) 161 assert.NoError(t, err) 162 assert.Len(t, doc8.NotSynchronizedOn, 0) 163 164 doc7, err := testInstance.VFS().DirByID(d7) 165 assert.NoError(t, err) 166 assert.Len(t, doc7.NotSynchronizedOn, 1) 167 doc9, err := testInstance.VFS().DirByID(d9) 168 assert.NoError(t, err) 169 assert.Len(t, doc9.NotSynchronizedOn, 1) 170 }) 171 } 172 173 func makeNotSynchronzedOnTestDir(t *testing.T, instance *instance.Instance, doc couchdb.Doc, name string) *vfs.DirDoc { 174 fs := instance.VFS() 175 dirID := consts.RootDirID 176 dir, err := vfs.NewDirDoc(fs, name, dirID, nil) 177 if !assert.NoError(t, err) { 178 return nil 179 } 180 181 if doc != nil { 182 dir.NotSynchronizedOn = []couchdb.DocReference{ 183 { 184 ID: doc.ID(), 185 Type: doc.DocType(), 186 }, 187 } 188 } 189 190 err = fs.CreateDir(dir) 191 192 if !assert.NoError(t, err) { 193 return nil 194 } 195 196 return dir 197 }