Merge "Add INFO.yaml"
[iec.git] / src / foundation / api / revel / params_test.go
1 // Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
2 // Revel Framework source code and usage is governed by a MIT style
3 // license that can be found in the LICENSE file.
4
5 package revel
6
7 import (
8         "bytes"
9         "fmt"
10         "io/ioutil"
11         "net/http"
12         "net/url"
13         "reflect"
14         "testing"
15 )
16
17 // Params: Testing Multipart forms
18
19 const (
20         MultipartBoundary = "A"
21         MultipartFormData = `--A
22 Content-Disposition: form-data; name="text1"
23
24 data1
25 --A
26 Content-Disposition: form-data; name="text2"
27
28 data2
29 --A
30 Content-Disposition: form-data; name="text2"
31
32 data3
33 --A
34 Content-Disposition: form-data; name="file1"; filename="test.txt"
35 Content-Type: text/plain
36
37 content1
38 --A
39 Content-Disposition: form-data; name="file2[]"; filename="test.txt"
40 Content-Type: text/plain
41
42 content2
43 --A
44 Content-Disposition: form-data; name="file2[]"; filename="favicon.ico"
45 Content-Type: image/x-icon
46
47 xyz
48 --A
49 Content-Disposition: form-data; name="file3[0]"; filename="test.txt"
50 Content-Type: text/plain
51
52 content3
53 --A
54 Content-Disposition: form-data; name="file3[1]"; filename="favicon.ico"
55 Content-Type: image/x-icon
56
57 zzz
58 --A--
59 `
60 )
61
62 // The values represented by the form data.
63 type fh struct {
64         filename string
65         content  []byte
66 }
67
68 var (
69         expectedValues = map[string][]string{
70                 "text1": {"data1"},
71                 "text2": {"data2", "data3"},
72         }
73         expectedFiles = map[string][]fh{
74                 "file1":    {fh{"test.txt", []byte("content1")}},
75                 "file2[]":  {fh{"test.txt", []byte("content2")}, fh{"favicon.ico", []byte("xyz")}},
76                 "file3[0]": {fh{"test.txt", []byte("content3")}},
77                 "file3[1]": {fh{"favicon.ico", []byte("zzz")}},
78         }
79 )
80
81 func getMultipartRequest() *http.Request {
82         req, _ := http.NewRequest("POST", "http://localhost/path",
83                 bytes.NewBufferString(MultipartFormData))
84         req.Header.Set(
85                 "Content-Type", fmt.Sprintf("multipart/form-data; boundary=%s", MultipartBoundary))
86         req.Header.Set(
87                 "Content-Length", fmt.Sprintf("%d", len(MultipartFormData)))
88         return req
89 }
90
91 func BenchmarkParams(b *testing.B) {
92         c := NewTestController(nil, showRequest)
93         c.Params = &Params{}
94
95         for i := 0; i < b.N; i++ {
96                 ParamsFilter(c, NilChain)
97         }
98 }
99
100 func TestMultipartForm(t *testing.T) {
101         c := NewTestController(nil, getMultipartRequest())
102         c.Params = &Params{}
103
104         ParamsFilter(c, NilChain)
105
106         if !reflect.DeepEqual(expectedValues, map[string][]string(c.Params.Values)) {
107                 t.Errorf("Param values: (expected) %v != %v (actual)",
108                         expectedValues, map[string][]string(c.Params.Values))
109         }
110
111         actualFiles := make(map[string][]fh)
112         for key, fileHeaders := range c.Params.Files {
113                 for _, fileHeader := range fileHeaders {
114                         file, _ := fileHeader.Open()
115                         content, _ := ioutil.ReadAll(file)
116                         actualFiles[key] = append(actualFiles[key], fh{fileHeader.Filename, content})
117                 }
118         }
119
120         if !reflect.DeepEqual(expectedFiles, actualFiles) {
121                 t.Errorf("Param files: (expected) %v != %v (actual)", expectedFiles, actualFiles)
122         }
123 }
124
125 func TestBind(t *testing.T) {
126         params := Params{
127                 Values: url.Values{
128                         "x": {"5"},
129                 },
130         }
131         var x int
132         params.Bind(&x, "x")
133         if x != 5 {
134                 t.Errorf("Failed to bind x.  Value: %d", x)
135         }
136 }
137
138 func TestResolveAcceptLanguage(t *testing.T) {
139         request := buildHTTPRequestWithAcceptLanguage("")
140         if result := ResolveAcceptLanguage(request); result != nil {
141                 t.Errorf("Expected Accept-Language to resolve to an empty string but it was '%s'", result)
142         }
143
144         request = buildHTTPRequestWithAcceptLanguage("en-GB,en;q=0.8,nl;q=0.6")
145         if result := ResolveAcceptLanguage(request); len(result) != 3 {
146                 t.Errorf("Unexpected Accept-Language values length of %d (expected %d)", len(result), 3)
147         } else {
148                 if result[0].Language != "en-GB" {
149                         t.Errorf("Expected '%s' to be most qualified but instead it's '%s'", "en-GB", result[0].Language)
150                 }
151                 if result[1].Language != "en" {
152                         t.Errorf("Expected '%s' to be most qualified but instead it's '%s'", "en", result[1].Language)
153                 }
154                 if result[2].Language != "nl" {
155                         t.Errorf("Expected '%s' to be most qualified but instead it's '%s'", "nl", result[2].Language)
156                 }
157         }
158
159         request = buildHTTPRequestWithAcceptLanguage("en;q=0.8,nl;q=0.6,en-AU;q=malformed")
160         if result := ResolveAcceptLanguage(request); len(result) != 3 {
161                 t.Errorf("Unexpected Accept-Language values length of %d (expected %d)", len(result), 3)
162         } else {
163                 if result[0].Language != "en-AU" {
164                         t.Errorf("Expected '%s' to be most qualified but instead it's '%s'", "en-AU", result[0].Language)
165                 }
166         }
167 }
168
169 func BenchmarkResolveAcceptLanguage(b *testing.B) {
170         for i := 0; i < b.N; i++ {
171                 request := buildHTTPRequestWithAcceptLanguage("en-GB,en;q=0.8,nl;q=0.6,fr;q=0.5,de-DE;q=0.4,no-NO;q=0.4,ru;q=0.2")
172                 ResolveAcceptLanguage(request)
173         }
174 }
175
176 func buildHTTPRequestWithAcceptLanguage(acceptLanguage string) *Request {
177         request, _ := http.NewRequest("POST", "http://localhost/path", nil)
178         request.Header.Set("Accept-Language", acceptLanguage)
179         c := NewTestController(nil, request)
180
181         return c.Request
182 }