github.com/jacobsoderblom/buffalo@v0.11.0/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  }