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  }