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