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  }