github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/web/files/referencedby_test.go (about) 1 package files 2 3 import ( 4 "net/url" 5 "testing" 6 7 "github.com/cozy/cozy-stack/pkg/config/config" 8 "github.com/cozy/cozy-stack/pkg/consts" 9 "github.com/cozy/cozy-stack/tests/testutils" 10 "github.com/cozy/cozy-stack/web/errors" 11 "github.com/cozy/cozy-stack/web/middlewares" 12 "github.com/gavv/httpexpect/v2" 13 "github.com/labstack/echo/v4" 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestReferencedby(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 var fileID1, fileID2 string 24 var fileData1, fileData2 *httpexpect.Object 25 26 config.UseTestFile(t) 27 require.NoError(t, loadLocale(), "Could not load default locale translations") 28 29 testutils.NeedCouchdb(t) 30 setup := testutils.NewSetup(t, t.Name()) 31 32 config.GetConfig().Fs.URL = &url.URL{ 33 Scheme: "file", 34 Host: "localhost", 35 Path: t.TempDir(), 36 } 37 38 testInstance := setup.GetTestInstance() 39 _, token := setup.GetTestClient(consts.Files + " " + consts.CertifiedCarbonCopy + " " + consts.CertifiedElectronicSafe) 40 ts := setup.GetTestServer("/files", Routes, func(r *echo.Echo) *echo.Echo { 41 secure := middlewares.Secure(&middlewares.SecureConfig{ 42 CSPDefaultSrc: []middlewares.CSPSource{middlewares.CSPSrcSelf}, 43 CSPFrameAncestors: []middlewares.CSPSource{middlewares.CSPSrcNone}, 44 }) 45 r.Use(secure) 46 return r 47 }) 48 ts.Config.Handler.(*echo.Echo).HTTPErrorHandler = errors.ErrorHandler 49 t.Cleanup(ts.Close) 50 51 t.Run("AddReferencedByOneRelation", func(t *testing.T) { 52 e := testutils.CreateTestClient(t, ts.URL) 53 54 obj := e.POST("/files/"). 55 WithQuery("Name", "toreference"). 56 WithQuery("Type", "file"). 57 WithHeader("Content-Type", "text/plain"). 58 WithHeader("Content-MD5", "UmfjCVWct/albVkURcJJfg=="). 59 WithHeader("Authorization", "Bearer "+token). 60 WithBytes([]byte("foo,bar")). 61 Expect().Status(201). 62 JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}). 63 Object() 64 65 fileData1 = obj.Value("data").Object() 66 fileID1 = fileData1.Value("id").String().NotEmpty().Raw() 67 meta1 := fileData1.Value("meta").Object() 68 rev1 := meta1.Value("rev").String().Raw() 69 70 obj = e.POST("/files/"+fileID1+"/relationships/referenced_by"). 71 WithHeader("Authorization", "Bearer "+token). 72 WithHeader("Content-Type", "application/json"). 73 WithBytes([]byte(`{ 74 "data": { 75 "id": "fooalbumid", 76 "type": "io.cozy.photos.albums" 77 } 78 }`)). 79 Expect().Status(200). 80 JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}). 81 Object() 82 83 rev2 := obj.Path("$.meta.rev").NotEqual(rev1).String().Raw() 84 obj.Path("$.meta.count").Equal(1) 85 data := obj.Value("data").Array() 86 data.Length().Equal(1) 87 elem := data.First().Object() 88 elem.ValueEqual("id", "fooalbumid") 89 elem.ValueEqual("type", "io.cozy.photos.albums") 90 91 doc, err := testInstance.VFS().FileByID(fileID1) 92 assert.NoError(t, err) 93 assert.Len(t, doc.ReferencedBy, 1) 94 assert.Equal(t, doc.Rev(), rev2) 95 }) 96 97 t.Run("AddReferencedByMultipleRelation", func(t *testing.T) { 98 e := testutils.CreateTestClient(t, ts.URL) 99 100 obj := e.POST("/files/"). 101 WithQuery("Name", "toreference2"). 102 WithQuery("Type", "file"). 103 WithHeader("Content-Type", "text/plain"). 104 WithHeader("Content-MD5", "UmfjCVWct/albVkURcJJfg=="). 105 WithHeader("Authorization", "Bearer "+token). 106 WithBytes([]byte("foo,bar")). 107 Expect().Status(201). 108 JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}). 109 Object() 110 111 fileData2 = obj.Value("data").Object() 112 fileID2 = fileData2.Value("id").String().NotEmpty().Raw() 113 meta1 := fileData2.Value("meta").Object() 114 rev1 := meta1.Value("rev").String().Raw() 115 116 obj = e.POST("/files/"+fileID2+"/relationships/referenced_by"). 117 WithHeader("Authorization", "Bearer "+token). 118 WithHeader("Content-Type", "application/json"). 119 WithBytes([]byte(`{ 120 "data": [ 121 { "id": "fooalbumid1", "type": "io.cozy.photos.albums" }, 122 { "id": "fooalbumid2", "type": "io.cozy.photos.albums" }, 123 { "id": "fooalbumid3", "type": "io.cozy.photos.albums" } 124 ] 125 }`)). 126 Expect().Status(200). 127 JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}). 128 Object() 129 130 rev2 := obj.Path("$.meta.rev").NotEqual(rev1).String().Raw() 131 data := obj.Value("data").Array() 132 data.Length().Equal(3) 133 134 elem := data.Element(0).Object() 135 elem.ValueEqual("id", "fooalbumid1") 136 elem.ValueEqual("type", "io.cozy.photos.albums") 137 elem = data.Element(1).Object() 138 elem.ValueEqual("id", "fooalbumid2") 139 elem.ValueEqual("type", "io.cozy.photos.albums") 140 elem = data.Element(2).Object() 141 elem.ValueEqual("id", "fooalbumid3") 142 elem.ValueEqual("type", "io.cozy.photos.albums") 143 144 doc, err := testInstance.VFS().FileByID(fileID2) 145 assert.NoError(t, err) 146 assert.Len(t, doc.ReferencedBy, 3) 147 assert.Equal(t, doc.Rev(), rev2) 148 }) 149 150 t.Run("RemoveReferencedByOneRelation", func(t *testing.T) { 151 e := testutils.CreateTestClient(t, ts.URL) 152 153 obj := e.DELETE("/files/"+fileID1+"/relationships/referenced_by"). 154 WithHeader("Authorization", "Bearer "+token). 155 WithHeader("Content-Type", "application/json"). 156 WithBytes([]byte(`{ 157 "data": { 158 "id": "fooalbumid", 159 "type": "io.cozy.photos.albums" 160 } 161 }`)). 162 Expect().Status(200). 163 JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}). 164 Object() 165 166 obj.Path("$.meta.count").Equal(0) 167 obj.Value("data").Array().Empty() 168 169 doc, err := testInstance.VFS().FileByID(fileID1) 170 assert.NoError(t, err) 171 assert.Len(t, doc.ReferencedBy, 0) 172 }) 173 174 t.Run("RemoveReferencedByMultipleRelation", func(t *testing.T) { 175 e := testutils.CreateTestClient(t, ts.URL) 176 177 obj := e.DELETE("/files/"+fileID2+"/relationships/referenced_by"). 178 WithHeader("Authorization", "Bearer "+token). 179 WithHeader("Content-Type", "application/json"). 180 WithBytes([]byte(`{ 181 "data": [ 182 { "id": "fooalbumid3", "type": "io.cozy.photos.albums" }, 183 { "id": "fooalbumid5", "type": "io.cozy.photos.albums" }, 184 { "id": "fooalbumid1", "type": "io.cozy.photos.albums" } 185 ] 186 }`)). 187 Expect().Status(200). 188 JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}). 189 Object() 190 191 obj.Path("$.meta.count").Equal(1) 192 data := obj.Value("data").Array() 193 data.Length().Equal(1) 194 elem := data.First().Object() 195 elem.ValueEqual("id", "fooalbumid2") 196 elem.ValueEqual("type", "io.cozy.photos.albums") 197 198 doc, err := testInstance.VFS().FileByID(fileID2) 199 assert.NoError(t, err) 200 assert.Len(t, doc.ReferencedBy, 1) 201 assert.Equal(t, "fooalbumid2", doc.ReferencedBy[0].ID) 202 }) 203 }