github.com/res-am/buffalo@v0.11.1/binding/file_test.go (about) 1 package binding_test 2 3 import ( 4 "bytes" 5 "io" 6 "mime/multipart" 7 "net/http" 8 "net/http/httptest" 9 "os" 10 "path/filepath" 11 "testing" 12 13 "github.com/gobuffalo/buffalo" 14 "github.com/gobuffalo/buffalo/binding" 15 "github.com/gobuffalo/buffalo/render" 16 "github.com/pkg/errors" 17 "github.com/stretchr/testify/require" 18 ) 19 20 type WithFile struct { 21 MyFile binding.File 22 } 23 24 type NamedFile struct { 25 MyFile binding.File `form:"afile"` 26 } 27 28 func App() *buffalo.App { 29 a := buffalo.New(buffalo.Options{}) 30 a.POST("/on-struct", func(c buffalo.Context) error { 31 wf := &WithFile{} 32 if err := c.Bind(wf); err != nil { 33 return errors.WithStack(err) 34 } 35 return c.Render(201, render.String(wf.MyFile.Filename)) 36 }) 37 a.POST("/named-file", func(c buffalo.Context) error { 38 wf := &NamedFile{} 39 if err := c.Bind(wf); err != nil { 40 return errors.WithStack(err) 41 } 42 return c.Render(201, render.String(wf.MyFile.Filename)) 43 }) 44 a.POST("/on-context", func(c buffalo.Context) error { 45 f, err := c.File("MyFile") 46 if err != nil { 47 return errors.WithStack(err) 48 } 49 return c.Render(201, render.String(f.Filename)) 50 }) 51 52 return a 53 } 54 55 func Test_File_Upload_On_Struct(t *testing.T) { 56 r := require.New(t) 57 58 req, err := newfileUploadRequest("/on-struct", "MyFile", "file_test.go") 59 r.NoError(err) 60 res := httptest.NewRecorder() 61 62 App().ServeHTTP(res, req) 63 64 r.Equal(201, res.Code) 65 r.Equal("file_test.go", res.Body.String()) 66 } 67 68 func Test_File_Upload_On_Struct_WithTag(t *testing.T) { 69 r := require.New(t) 70 71 req, err := newfileUploadRequest("/named-file", "afile", "file_test.go") 72 r.NoError(err) 73 res := httptest.NewRecorder() 74 75 App().ServeHTTP(res, req) 76 77 r.Equal(201, res.Code) 78 r.Equal("file_test.go", res.Body.String()) 79 } 80 81 func Test_File_Upload_On_Context(t *testing.T) { 82 r := require.New(t) 83 84 req, err := newfileUploadRequest("/on-context", "MyFile", "file_test.go") 85 r.NoError(err) 86 res := httptest.NewRecorder() 87 88 App().ServeHTTP(res, req) 89 90 r.Equal(201, res.Code) 91 r.Equal("file_test.go", res.Body.String()) 92 } 93 94 // this helper method was inspired by this blog post by Matt Aimonetti: 95 // https://matt.aimonetti.net/posts/2013/07/01/golang-multipart-file-upload-example/ 96 func newfileUploadRequest(uri string, paramName, path string) (*http.Request, error) { 97 file, err := os.Open(path) 98 if err != nil { 99 return nil, err 100 } 101 defer file.Close() 102 103 body := &bytes.Buffer{} 104 writer := multipart.NewWriter(body) 105 part, err := writer.CreateFormFile(paramName, filepath.Base(path)) 106 if err != nil { 107 return nil, err 108 } 109 _, err = io.Copy(part, file) 110 111 err = writer.Close() 112 if err != nil { 113 return nil, err 114 } 115 116 req, err := http.NewRequest("POST", uri, body) 117 req.Header.Set("Content-Type", writer.FormDataContentType()) 118 return req, err 119 }