github.com/System-Glitch/goyave/v2@v2.10.3-0.20200819142921-51011e75d504/validation/files_test.go (about) 1 package validation 2 3 import ( 4 "bytes" 5 "io" 6 "mime/multipart" 7 "net/http" 8 "os" 9 "path" 10 "path/filepath" 11 "runtime" 12 "testing" 13 14 "github.com/System-Glitch/goyave/v2/helper/filesystem" 15 "github.com/stretchr/testify/assert" 16 ) 17 18 const ( 19 logoPath string = "resources/img/logo/goyave_16.png" 20 mediumLogoPath string = "resources/img/logo/goyave_128.png" 21 largeLogoPath string = "resources/img/logo/goyave_512.png" 22 configPath string = "config/config.test.json" 23 utf8BOMPath string = "resources/test_file.txt" 24 ) 25 26 func addFileToRequest(writer *multipart.Writer, path, name, fileName string) { 27 file, err := os.Open(path) 28 if err != nil { 29 panic(err) 30 } 31 defer file.Close() 32 part, err := writer.CreateFormFile(name, fileName) 33 if err != nil { 34 panic(err) 35 } 36 _, err = io.Copy(part, file) 37 if err != nil { 38 panic(err) 39 } 40 } 41 42 func createTestFiles(files ...string) []filesystem.File { 43 _, filename, _, _ := runtime.Caller(1) 44 45 body := &bytes.Buffer{} 46 writer := multipart.NewWriter(body) 47 for _, p := range files { 48 fp := path.Dir(filename) + "/../" + p 49 addFileToRequest(writer, fp, "file", filepath.Base(fp)) 50 } 51 err := writer.Close() 52 if err != nil { 53 panic(err) 54 } 55 56 req, err := http.NewRequest("POST", "/test-route", body) 57 if err != nil { 58 panic(err) 59 } 60 req.Header.Set("Content-Type", writer.FormDataContentType()) 61 if err := req.ParseMultipartForm(10 << 20); err != nil { 62 panic(err) 63 } 64 return filesystem.ParseMultipartFiles(req, "file") 65 } 66 67 func createTestFileWithNoExtension() []filesystem.File { 68 _, filename, _, _ := runtime.Caller(1) 69 70 body := &bytes.Buffer{} 71 writer := multipart.NewWriter(body) 72 addFileToRequest(writer, path.Dir(filename)+"/../"+logoPath, "file", "noextension") 73 err := writer.Close() 74 if err != nil { 75 panic(err) 76 } 77 78 req, err := http.NewRequest("POST", "/test-route", body) 79 if err != nil { 80 panic(err) 81 } 82 req.Header.Set("Content-Type", writer.FormDataContentType()) 83 if err := req.ParseMultipartForm(10 << 20); err != nil { 84 panic(err) 85 } 86 return filesystem.ParseMultipartFiles(req, "file") 87 } 88 89 func TestValidateFile(t *testing.T) { 90 assert.True(t, validateFile("file", createTestFiles(logoPath), []string{}, map[string]interface{}{})) 91 assert.True(t, validateFile("file", createTestFiles(logoPath, configPath), []string{}, map[string]interface{}{})) 92 assert.False(t, validateFile("file", "test", []string{}, map[string]interface{}{})) 93 assert.False(t, validateFile("file", 1, []string{}, map[string]interface{}{})) 94 assert.False(t, validateFile("file", 1.2, []string{}, map[string]interface{}{})) 95 assert.False(t, validateFile("file", true, []string{}, map[string]interface{}{})) 96 assert.False(t, validateFile("file", []string{}, []string{}, map[string]interface{}{})) 97 } 98 99 func TestValidateMIME(t *testing.T) { 100 assert.True(t, validateMIME("file", createTestFiles(logoPath), []string{"image/png"}, map[string]interface{}{})) 101 assert.True(t, validateMIME("file", createTestFiles(logoPath), []string{"text/plain", "image/png"}, map[string]interface{}{})) 102 assert.True(t, validateMIME("file", createTestFiles(utf8BOMPath), []string{"text/plain", "image/jpeg"}, map[string]interface{}{})) 103 assert.True(t, validateMIME("file", createTestFiles(utf8BOMPath, logoPath), []string{"text/plain", "image/png"}, map[string]interface{}{})) 104 assert.False(t, validateMIME("file", createTestFiles(utf8BOMPath, logoPath), []string{"text/plain"}, map[string]interface{}{})) 105 assert.False(t, validateMIME("file", createTestFiles(logoPath), []string{"text/plain", "image/jpeg"}, map[string]interface{}{})) 106 assert.False(t, validateMIME("file", "test", []string{"text/plain", "image/jpeg"}, map[string]interface{}{})) 107 108 assert.Panics(t, func() { 109 field := &Field{ 110 Rules: []*Rule{ 111 {Name: "mime"}, 112 }, 113 } 114 field.check() 115 }) 116 } 117 118 func TestValidateImage(t *testing.T) { 119 assert.True(t, validateImage("file", createTestFiles(logoPath), []string{}, map[string]interface{}{})) 120 assert.False(t, validateImage("file", createTestFiles(configPath), []string{}, map[string]interface{}{})) 121 assert.False(t, validateImage("file", createTestFiles(logoPath, configPath), []string{}, map[string]interface{}{})) 122 } 123 124 func TestValidateExtension(t *testing.T) { 125 assert.True(t, validateExtension("file", createTestFiles(logoPath), []string{"png", "jpeg"}, map[string]interface{}{})) 126 assert.True(t, validateExtension("file", createTestFiles(logoPath, configPath), []string{"png", "json"}, map[string]interface{}{})) 127 assert.False(t, validateExtension("file", createTestFiles(logoPath), []string{"jpeg"}, map[string]interface{}{})) 128 assert.False(t, validateExtension("file", createTestFiles(logoPath, configPath), []string{"png"}, map[string]interface{}{})) 129 assert.False(t, validateExtension("file", createTestFileWithNoExtension(), []string{"png"}, map[string]interface{}{})) 130 assert.False(t, validateExtension("file", "test", []string{"png"}, map[string]interface{}{})) 131 132 assert.Panics(t, func() { 133 field := &Field{ 134 Rules: []*Rule{ 135 {Name: "extension"}, 136 }, 137 } 138 field.check() 139 }) 140 } 141 142 func TestValidateCount(t *testing.T) { 143 assert.True(t, validateCount("file", createTestFiles(logoPath, configPath), []string{"2"}, map[string]interface{}{})) 144 assert.False(t, validateCount("file", createTestFiles(logoPath, configPath), []string{"3"}, map[string]interface{}{})) 145 146 assert.False(t, validateCount("file", "test", []string{"3"}, map[string]interface{}{})) 147 assert.Panics(t, func() { validateCount("file", true, []string{"test"}, map[string]interface{}{}) }) 148 149 assert.Panics(t, func() { 150 field := &Field{ 151 Rules: []*Rule{ 152 {Name: "count"}, 153 }, 154 } 155 field.check() 156 }) 157 } 158 159 func TestValidateCountMin(t *testing.T) { 160 assert.True(t, validateCountMin("file", createTestFiles(logoPath, configPath), []string{"2"}, map[string]interface{}{})) 161 assert.False(t, validateCountMin("file", createTestFiles(logoPath, configPath), []string{"3"}, map[string]interface{}{})) 162 163 assert.False(t, validateCountMin("file", "test", []string{"3"}, map[string]interface{}{})) 164 assert.Panics(t, func() { validateCountMin("file", true, []string{"test"}, map[string]interface{}{}) }) 165 166 assert.Panics(t, func() { 167 field := &Field{ 168 Rules: []*Rule{ 169 {Name: "count_min"}, 170 }, 171 } 172 field.check() 173 }) 174 } 175 176 func TestValidateCountMax(t *testing.T) { 177 assert.True(t, validateCountMax("file", createTestFiles(logoPath, configPath), []string{"2"}, map[string]interface{}{})) 178 assert.False(t, validateCountMax("file", createTestFiles(logoPath, configPath), []string{"1"}, map[string]interface{}{})) 179 180 assert.False(t, validateCountMax("file", "test", []string{"3"}, map[string]interface{}{})) 181 assert.Panics(t, func() { validateCountMax("file", true, []string{"test"}, map[string]interface{}{}) }) 182 183 assert.Panics(t, func() { 184 field := &Field{ 185 Rules: []*Rule{ 186 {Name: "count_max"}, 187 }, 188 } 189 field.check() 190 }) 191 } 192 193 func TestValidateCountBetween(t *testing.T) { 194 assert.True(t, validateCountBetween("file", createTestFiles(logoPath, configPath), []string{"1", "5"}, map[string]interface{}{})) 195 assert.False(t, validateCountBetween("file", createTestFiles(logoPath, largeLogoPath, configPath), []string{"1", "2"}, map[string]interface{}{})) 196 assert.False(t, validateCountBetween("file", createTestFiles(logoPath, configPath), []string{"3", "5"}, map[string]interface{}{})) 197 198 assert.False(t, validateCountBetween("file", "test", []string{"3", "4"}, map[string]interface{}{})) 199 assert.Panics(t, func() { validateCountBetween("file", true, []string{"test", "2"}, map[string]interface{}{}) }) 200 assert.Panics(t, func() { validateCountBetween("file", true, []string{"2", "test"}, map[string]interface{}{}) }) 201 assert.Panics(t, func() { validateCountBetween("file", true, []string{"test", "test"}, map[string]interface{}{}) }) 202 203 assert.Panics(t, func() { 204 field := &Field{ 205 Rules: []*Rule{ 206 {Name: "count_between"}, 207 }, 208 } 209 field.check() 210 }) 211 212 assert.Panics(t, func() { 213 field := &Field{ 214 Rules: []*Rule{ 215 {Name: "count_between", Params: []string{"2"}}, 216 }, 217 } 218 field.check() 219 }) 220 }