github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/sys/it/impl_blob_test.go (about) 1 /* 2 * Copyright (c) 2022-present unTill Pro, Ltd. 3 */ 4 5 package sys_it 6 7 import ( 8 "fmt" 9 "log" 10 "testing" 11 12 "github.com/stretchr/testify/require" 13 14 "github.com/voedger/voedger/pkg/istructs" 15 payloads "github.com/voedger/voedger/pkg/itokens-payloads" 16 coreutils "github.com/voedger/voedger/pkg/utils" 17 it "github.com/voedger/voedger/pkg/vit" 18 ) 19 20 func TestBasicUsage_BLOBProcessors(t *testing.T) { 21 require := require.New(t) 22 vit := it.NewVIT(t, &it.SharedConfig_App1) 23 defer vit.TearDown() 24 25 as, err := vit.AppStructs(istructs.AppQName_test1_app1) 26 require.NoError(err) 27 systemPrincipal, err := payloads.GetSystemPrincipalTokenApp(as.AppTokens()) 28 require.NoError(err) 29 30 expBLOB := []byte{1, 2, 3, 4, 5} 31 32 ws := vit.WS(istructs.AppQName_test1_app1, "test_ws") 33 34 // write 35 blobID := vit.UploadBLOB(istructs.AppQName_test1_app1, ws.WSID, "test", coreutils.ApplicationXBinary, expBLOB, 36 coreutils.WithAuthorizeBy(systemPrincipal), 37 coreutils.WithHeaders("Content-Type", "application/x-www-form-urlencoded"), // has name+mimeType query params -> any Content-Type except "multipart/form-data" is allowed 38 ) 39 log.Println(blobID) 40 41 // read, authorize over headers 42 resp := vit.ReadBLOB(istructs.AppQName_test1_app1, ws.WSID, blobID, 43 coreutils.WithAuthorizeBy(systemPrincipal), 44 ) 45 actBLOB := []byte(resp.Body) 46 require.Equal("application/x-binary", resp.HTTPResp.Header["Content-Type"][0]) 47 require.Equal(`attachment;filename="test"`, resp.HTTPResp.Header["Content-Disposition"][0]) 48 require.Equal(expBLOB, actBLOB) 49 50 // read, authorize over unescaped cookies 51 resp = vit.ReadBLOB(istructs.AppQName_test1_app1, ws.WSID, blobID, 52 coreutils.WithCookies(coreutils.Authorization, "Bearer "+systemPrincipal), 53 ) 54 actBLOB = []byte(resp.Body) 55 require.Equal("application/x-binary", resp.HTTPResp.Header["Content-Type"][0]) 56 require.Equal(`attachment;filename="test"`, resp.HTTPResp.Header["Content-Disposition"][0]) 57 require.Equal(expBLOB, actBLOB) 58 59 // read, authorize over escaped cookies 60 resp = vit.ReadBLOB(istructs.AppQName_test1_app1, ws.WSID, blobID, 61 coreutils.WithCookies(coreutils.Authorization, "Bearer%20"+systemPrincipal), 62 ) 63 actBLOB = []byte(resp.Body) 64 require.Equal("application/x-binary", resp.HTTPResp.Header["Content-Type"][0]) 65 require.Equal(`attachment;filename="test"`, resp.HTTPResp.Header["Content-Disposition"][0]) 66 require.Equal(expBLOB, actBLOB) 67 68 // read, POST 69 resp = vit.ReadBLOB(istructs.AppQName_test1_app1, ws.WSID, blobID, 70 coreutils.WithAuthorizeBy(systemPrincipal), 71 ) 72 actBLOB = []byte(resp.Body) 73 require.Equal("application/x-binary", resp.HTTPResp.Header["Content-Type"][0]) 74 require.Equal(`attachment;filename="test"`, resp.HTTPResp.Header["Content-Disposition"][0]) 75 require.Equal(expBLOB, actBLOB) 76 77 } 78 79 func TestBlobberErrors(t *testing.T) { 80 require := require.New(t) 81 vit := it.NewVIT(t, &it.SharedConfig_App1) 82 defer vit.TearDown() 83 84 ws := vit.WS(istructs.AppQName_test1_app1, "test_ws") 85 86 as, err := vit.AppStructs(istructs.AppQName_test1_app1) 87 require.NoError(err) 88 systemPrincipal, err := payloads.GetSystemPrincipalTokenApp(as.AppTokens()) 89 require.NoError(err) 90 91 t.Run("401 unauthorized on no authorization token in neither headers nor cookies", func(t *testing.T) { 92 vit.UploadBLOB(istructs.AppQName_test1_app1, ws.WSID, "test", coreutils.ApplicationXBinary, []byte{}, 93 coreutils.Expect401(), 94 ) 95 }) 96 97 t.Run("403 forbidden on blob size quota exceeded", func(t *testing.T) { 98 bigBLOB := make([]byte, 150) 99 vit.UploadBLOB(istructs.AppQName_test1_app1, ws.WSID, "test", coreutils.ApplicationXBinary, bigBLOB, 100 coreutils.WithAuthorizeBy(systemPrincipal), 101 coreutils.Expect403(), 102 ) 103 }) 104 105 t.Run("404 not found on querying an unexsting blob", func(t *testing.T) { 106 vit.ReadBLOB(istructs.AppQName_test1_app1, ws.WSID, 1, 107 coreutils.WithAuthorizeBy(systemPrincipal), 108 coreutils.Expect404(), 109 ).Println() 110 }) 111 112 t.Run("400 on wrong Content-Type and name+mimeType query params", func(t *testing.T) { 113 t.Run("neither Content-Type nor name+mimeType query params are not provided", func(t *testing.T) { 114 vit.POST(fmt.Sprintf(`blob/test1/app1/%d`, ws.WSID), "blobContent", 115 coreutils.WithAuthorizeBy(systemPrincipal), 116 coreutils.Expect400(), 117 ).Println() 118 }) 119 t.Run("no name+mimeType query params and non-(mutipart/form-data) Content-Type", func(t *testing.T) { 120 vit.POST(fmt.Sprintf(`blob/test1/app1/%d`, ws.WSID), "blobContent", 121 coreutils.WithAuthorizeBy(systemPrincipal), 122 coreutils.WithHeaders("Content-Type", "application/x-www-form-urlencoded"), 123 coreutils.Expect400(), 124 ).Println() 125 }) 126 t.Run("both name+mimeType query params and Conten-Type are specified", func(t *testing.T) { 127 vit.POST(fmt.Sprintf(`blob/test1/app1/%d?name=test&mimeType=application/x-binary`, ws.WSID), "blobContent", 128 coreutils.WithAuthorizeBy(systemPrincipal), 129 coreutils.WithHeaders("Content-Type", "multipart/form-data"), 130 coreutils.Expect400(), 131 ).Println() 132 }) 133 t.Run("boundary of multipart/form-data is not specified", func(t *testing.T) { 134 vit.POST(fmt.Sprintf(`blob/test1/app1/%d`, ws.WSID), "blobContent", 135 coreutils.WithAuthorizeBy(systemPrincipal), 136 coreutils.WithHeaders("Content-Type", "multipart/form-data"), 137 coreutils.Expect400(), 138 ).Println() 139 }) 140 }) 141 } 142 143 func TestBlobMultipartUpload(t *testing.T) { 144 require := require.New(t) 145 vit := it.NewVIT(t, &it.SharedConfig_App1) 146 defer vit.TearDown() 147 148 ws := vit.WS(istructs.AppQName_test1_app1, "test_ws") 149 150 blobs := []coreutils.BLOB{ 151 { 152 Content: []byte{1, 2, 3, 4, 5}, 153 Name: "blob1", 154 }, 155 { 156 Content: []byte{6, 7, 8, 9, 10}, 157 Name: "blob2", 158 }, 159 } 160 161 as, err := vit.AppStructs(istructs.AppQName_test1_app1) 162 require.NoError(err) 163 systemPrincipalToken, err := payloads.GetSystemPrincipalTokenApp(as.AppTokens()) 164 require.NoError(err) 165 blobIDs := vit.UploadBLOBs(istructs.AppQName_test1_app1, ws.WSID, blobs, 166 coreutils.WithAuthorizeBy(systemPrincipalToken)) 167 168 // read blob1 169 actualBLOB1 := vit.GetBLOB(istructs.AppQName_test1_app1, ws.WSID, blobIDs[0], systemPrincipalToken) 170 require.Equal("application/x-binary", actualBLOB1.MimeType) 171 require.Equal(`blob1`, actualBLOB1.Name) 172 require.Equal(blobs[0].Content, actualBLOB1.Content) 173 174 // read blob2 175 actualBLOB2 := vit.GetBLOB(istructs.AppQName_test1_app1, ws.WSID, blobIDs[1], systemPrincipalToken) 176 require.Equal("application/x-binary", actualBLOB2.MimeType) 177 require.Equal(`blob2`, actualBLOB2.Name) 178 require.Equal(blobs[1].Content, actualBLOB2.Content) 179 }