Add API Framework Revel Source Files
[iec.git] / src / foundation / api / revel / validators_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_test
6
7 import (
8         "fmt"
9         "github.com/revel/revel"
10         "net"
11         "reflect"
12         "regexp"
13         "strings"
14         "testing"
15         "time"
16 )
17
18 const (
19         errorsMessage   = "validation for %s should not be satisfied with %s\n"
20         noErrorsMessage = "validation for %s should be satisfied with %s\n"
21 )
22
23 type Expect struct {
24         input          interface{}
25         expectedResult bool
26         errorMessage   string
27 }
28
29 func performTests(validator revel.Validator, tests []Expect, t *testing.T) {
30         for _, test := range tests {
31                 if validator.IsSatisfied(test.input) != test.expectedResult {
32                         if test.expectedResult {
33                                 t.Errorf(noErrorsMessage, reflect.TypeOf(validator), test.errorMessage)
34                         } else {
35                                 t.Errorf(errorsMessage, reflect.TypeOf(validator), test.errorMessage)
36                         }
37                 }
38         }
39 }
40
41 func TestRequired(t *testing.T) {
42         tests := []Expect{
43                 {nil, false, "nil data"},
44                 {"Testing", true, "non-empty string"},
45                 {"", false, "empty string"},
46                 {true, true, "true boolean"},
47                 {false, false, "false boolean"},
48                 {1, true, "positive integer"},
49                 {-1, true, "negative integer"},
50                 {0, false, "0 integer"},
51                 {time.Now(), true, "current time"},
52                 {time.Time{}, false, "a zero time"},
53                 {func() {}, true, "other non-nil data types"},
54                 {net.IP(""), false, "empty IP address"},
55         }
56
57         // testing both the struct and the helper method
58         for _, required := range []revel.Required{{}, revel.ValidRequired()} {
59                 performTests(required, tests, t)
60         }
61 }
62
63 func TestMin(t *testing.T) {
64         tests := []Expect{
65                 {11, true, "val > min"},
66                 {10, true, "val == min"},
67                 {9, false, "val < min"},
68                 {true, false, "TypeOf(val) != int"},
69         }
70         for _, min := range []revel.Min{{10}, revel.ValidMin(10)} {
71                 performTests(min, tests, t)
72         }
73 }
74
75 func TestMax(t *testing.T) {
76         tests := []Expect{
77                 {9, true, "val < max"},
78                 {10, true, "val == max"},
79                 {11, false, "val > max"},
80                 {true, false, "TypeOf(val) != int"},
81         }
82         for _, max := range []revel.Max{{10}, revel.ValidMax(10)} {
83                 performTests(max, tests, t)
84         }
85 }
86
87 func TestRange(t *testing.T) {
88         tests := []Expect{
89                 {50, true, "min <= val <= max"},
90                 {10, true, "val == min"},
91                 {100, true, "val == max"},
92                 {9, false, "val < min"},
93                 {101, false, "val > max"},
94         }
95
96         goodValidators := []revel.Range{
97                 {revel.Min{10}, revel.Max{100}},
98                 revel.ValidRange(10, 100),
99         }
100         for _, rangeValidator := range goodValidators {
101                 performTests(rangeValidator, tests, t)
102         }
103
104         testsFloat := []Expect{
105                 {50, true, "min <= val <= max"},
106                 {10.25, true, "val == min"},
107                 {100, true, "val == max"},
108                 {9, false, "val < min"},
109                 {101, false, "val > max"},
110         }
111         goodValidatorsFloat := []revel.Range{
112                 {revel.Min{10.25}, revel.Max{100.5}},
113                 revel.ValidRangeFloat(10.25, 100.5),
114         }
115         for _, rangeValidator := range goodValidatorsFloat {
116                 performTests(rangeValidator, testsFloat, t)
117         }
118
119         tests = []Expect{
120                 {10, true, "min == val == max"},
121                 {9, false, "val < min && val < max && min == max"},
122                 {11, false, "val > min && val > max && min == max"},
123         }
124
125         goodValidators = []revel.Range{
126                 {revel.Min{10}, revel.Max{10}},
127                 revel.ValidRange(10, 10),
128         }
129         for _, rangeValidator := range goodValidators {
130                 performTests(rangeValidator, tests, t)
131         }
132
133         tests = make([]Expect, 7)
134         for i, num := range []int{50, 100, 10, 9, 101, 0, -1} {
135                 tests[i] = Expect{
136                         num,
137                         false,
138                         "min > val < max",
139                 }
140         }
141         // these are min/max with values swapped, so the min is the high
142         // and max is the low. rangeValidator.IsSatisfied() should ALWAYS
143         // result in false since val can never be greater than min and less
144         // than max when min > max
145         badValidators := []revel.Range{
146                 {revel.Min{100}, revel.Max{10}},
147                 revel.ValidRange(100, 10),
148         }
149         for _, rangeValidator := range badValidators {
150                 performTests(rangeValidator, tests, t)
151         }
152
153         badValidatorsFloat := []revel.Range{
154                 {revel.Min{100}, revel.Max{10}},
155                 revel.ValidRangeFloat(100, 10),
156         }
157         for _, rangeValidator := range badValidatorsFloat {
158                 performTests(rangeValidator, tests, t)
159         }
160 }
161
162 func TestMinSize(t *testing.T) {
163         greaterThanMessage := "len(val) >= min"
164         tests := []Expect{
165                 {"12", true, greaterThanMessage},
166                 {"123", true, greaterThanMessage},
167                 {[]int{1, 2}, true, greaterThanMessage},
168                 {[]int{1, 2, 3}, true, greaterThanMessage},
169                 {"", false, "len(val) <= min"},
170                 {"手", false, "len(val) <= min"},
171                 {[]int{}, false, "len(val) <= min"},
172                 {nil, false, "TypeOf(val) != string && TypeOf(val) != slice"},
173         }
174
175         for _, minSize := range []revel.MinSize{{2}, revel.ValidMinSize(2)} {
176                 performTests(minSize, tests, t)
177         }
178 }
179
180 func TestMaxSize(t *testing.T) {
181         lessThanMessage := "len(val) <= max"
182         tests := []Expect{
183                 {"", true, lessThanMessage},
184                 {"12", true, lessThanMessage},
185                 {"ルビー", true, lessThanMessage},
186                 {[]int{}, true, lessThanMessage},
187                 {[]int{1, 2}, true, lessThanMessage},
188                 {[]int{1, 2, 3}, true, lessThanMessage},
189                 {"1234", false, "len(val) >= max"},
190                 {[]int{1, 2, 3, 4}, false, "len(val) >= max"},
191         }
192         for _, maxSize := range []revel.MaxSize{{3}, revel.ValidMaxSize(3)} {
193                 performTests(maxSize, tests, t)
194         }
195 }
196
197 func TestLength(t *testing.T) {
198         tests := []Expect{
199                 {"12", true, "len(val) == length"},
200                 {"火箭", true, "len(val) == length"},
201                 {[]int{1, 2}, true, "len(val) == length"},
202                 {"123", false, "len(val) > length"},
203                 {[]int{1, 2, 3}, false, "len(val) > length"},
204                 {"1", false, "len(val) < length"},
205                 {[]int{1}, false, "len(val) < length"},
206                 {nil, false, "TypeOf(val) != string && TypeOf(val) != slice"},
207         }
208         for _, length := range []revel.Length{{2}, revel.ValidLength(2)} {
209                 performTests(length, tests, t)
210         }
211 }
212
213 func TestMatch(t *testing.T) {
214         tests := []Expect{
215                 {"bca123", true, `"[abc]{3}\d*" matches "bca123"`},
216                 {"bc123", false, `"[abc]{3}\d*" does not match "bc123"`},
217                 {"", false, `"[abc]{3}\d*" does not match ""`},
218         }
219         regex := regexp.MustCompile(`[abc]{3}\d*`)
220         for _, match := range []revel.Match{{regex}, revel.ValidMatch(regex)} {
221                 performTests(match, tests, t)
222         }
223 }
224
225 func TestEmail(t *testing.T) {
226         // unicode char included
227         validStartingCharacters := strings.Split("!#$%^&*_+1234567890abcdefghijklmnopqrstuvwxyzñ", "")
228         invalidCharacters := strings.Split(" ()", "")
229
230         definiteInvalidDomains := []string{
231                 "",                  // any empty string (x@)
232                 ".com",              // only the TLD (x@.com)
233                 ".",                 // only the . (x@.)
234                 ".*",                // TLD containing symbol (x@.*)
235                 "asdf",              // no TLD
236                 "a!@#$%^&*()+_.com", // characters which are not ASCII/0-9/dash(-) in a domain
237                 "-a.com",            // host starting with any symbol
238                 "a-.com",            // host ending with any symbol
239                 "aå.com",            // domain containing unicode (however, unicode domains do exist in the state of xn--<POINT>.com e.g. å.com = xn--5ca.com)
240         }
241
242         // Email pattern is not exposed
243         emailPattern := regexp.MustCompile("^[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?$")
244         for _, email := range []revel.Email{{revel.Match{emailPattern}}, revel.ValidEmail()} {
245                 var currentEmail string
246
247                 // test invalid starting chars
248                 for _, startingChar := range validStartingCharacters {
249                         currentEmail = fmt.Sprintf("%sñbc+123@do-main.com", startingChar)
250                         if email.IsSatisfied(currentEmail) {
251                                 t.Errorf(noErrorsMessage, "starting characters", fmt.Sprintf("email = %s", currentEmail))
252                         }
253
254                         // validation should fail because of multiple @ symbols
255                         currentEmail = fmt.Sprintf("%s@ñbc+123@do-main.com", startingChar)
256                         if email.IsSatisfied(currentEmail) {
257                                 t.Errorf(errorsMessage, "starting characters with multiple @ symbols", fmt.Sprintf("email = %s", currentEmail))
258                         }
259
260                         // should fail simply because of the invalid char
261                         for _, invalidChar := range invalidCharacters {
262                                 currentEmail = fmt.Sprintf("%sñbc%s+123@do-main.com", startingChar, invalidChar)
263                                 if email.IsSatisfied(currentEmail) {
264                                         t.Errorf(errorsMessage, "invalid starting characters", fmt.Sprintf("email = %s", currentEmail))
265                                 }
266                         }
267                 }
268
269                 // test invalid domains
270                 for _, invalidDomain := range definiteInvalidDomains {
271                         currentEmail = fmt.Sprintf("a@%s", invalidDomain)
272                         if email.IsSatisfied(currentEmail) {
273                                 t.Errorf(errorsMessage, "invalid domain", fmt.Sprintf("email = %s", currentEmail))
274                         }
275                 }
276
277                 // should always be satisfied
278                 if !email.IsSatisfied("t0.est+email123@1abc0-def.com") {
279                         t.Errorf(noErrorsMessage, "guaranteed valid email", fmt.Sprintf("email = %s", "t0.est+email123@1abc0-def.com"))
280                 }
281
282                 // should never be satisfied (this is redundant given the loops above)
283                 if email.IsSatisfied("a@xcom") {
284                         t.Errorf(noErrorsMessage, "guaranteed invalid email", fmt.Sprintf("email = %s", "a@xcom"))
285                 }
286                 if email.IsSatisfied("a@@x.com") {
287                         t.Errorf(noErrorsMessage, "guaranteed invalid email", fmt.Sprintf("email = %s", "a@@x.com"))
288                 }
289         }
290 }
291
292 func runIPAddrTestfunc(t *testing.T, test_type int, ipaddr_list map[string]bool, msg_fmt string) {
293
294         // generate dataset for test
295         test_ipaddr_list := []Expect{}
296         for ipaddr, expected := range ipaddr_list {
297                 test_ipaddr_list = append(test_ipaddr_list, Expect{input: ipaddr, expectedResult: expected, errorMessage: fmt.Sprintf(msg_fmt, ipaddr)})
298         }
299
300         for _, ip_test_list := range []revel.IPAddr{{[]int{test_type}}, revel.ValidIPAddr(test_type)} {
301                 performTests(ip_test_list, test_ipaddr_list, t)
302         }
303 }
304
305 func TestIPAddr(t *testing.T) {
306
307         //IPv4
308         test_ipv4_ipaddrs := map[string]bool{
309                 "192.168.1.1":     true,
310                 "127.0.0.1":       true,
311                 "10.10.90.12":     true,
312                 "8.8.8.8":         true,
313                 "4.4.4.4":         true,
314                 "912.456.123.123": false,
315                 "999.999.999.999": false,
316                 "192.192.19.999":  false,
317         }
318
319         //IPv4 with CIDR
320         test_ipv4_with_cidr_ipaddrs := map[string]bool{
321                 "192.168.1.1/24": true,
322                 "127.0.0.1/32":   true,
323                 "10.10.90.12/8":  true,
324                 "8.8.8.8/1":      true,
325                 "4.4.4.4/7":      true,
326                 "192.168.1.1/99": false,
327                 "127.0.0.1/9999": false,
328                 "10.10.90.12/33": false,
329                 "8.8.8.8/128":    false,
330                 "4.4.4.4/256":    false,
331         }
332
333         //IPv6
334         test_ipv6_ipaddrs := map[string]bool{
335                 "2607:f0d0:1002:51::4":                    true,
336                 "2607:f0d0:1002:0051:0000:0000:0000:0004": true,
337                 "ff05::1:3":                               true,
338                 "FE80:0000:0000:0000:0202:B3FF:FE1E:8329": true,
339                 "FE80::0202:B3FF:FE1E:8329":               true,
340                 "fe80::202:b3ff:fe1e:8329":                true,
341                 "fe80:0000:0000:0000:0202:b3ff:fe1e:8329": true,
342                 "2001:470:1f09:495::3":                    true,
343                 "2001:470:1f1d:275::1":                    true,
344                 "2600:9000:5304:200::1":                   true,
345                 "2600:9000:5306:d500::1":                  true,
346                 "2600:9000:5301:b600::1":                  true,
347                 "2600:9000:5303:900::1":                   true,
348                 "127:12:12:12:12:12:!2:!2":                false,
349                 "127.0.0.1":                               false,
350                 "234:23:23:23:23:23:23":                   false,
351         }
352
353         //IPv6 with CIDR
354         test_ipv6_with_cidr_ipaddrs := map[string]bool{
355                 "2000::/5":      true,
356                 "2000::/15":     true,
357                 "2001:db8::/33": true,
358                 "2001:db8::/48": true,
359                 "fc00::/7":      true,
360         }
361
362         //IPv4-Mapped Embedded IPv6 Address
363         test_ipv4_mapped_ipv6_ipaddrs := map[string]bool{
364                 "2001:470:1f09:495::3:217.126.185.215":         true,
365                 "2001:470:1f1d:275::1:213.0.69.132":            true,
366                 "2600:9000:5304:200::1:205.251.196.2":          true,
367                 "2600:9000:5306:d500::1:205.251.198.213":       true,
368                 "2600:9000:5301:b600::1:205.251.193.182":       true,
369                 "2600:9000:5303:900::1:205.251.195.9":          true,
370                 "0:0:0:0:0:FFFF:222.1.41.90":                   true,
371                 "::FFFF:222.1.41.90":                           true,
372                 "0000:0000:0000:0000:0000:FFFF:12.155.166.101": true,
373                 "12.155.166.101":                               false,
374                 "12.12/12":                                     false,
375         }
376
377         runIPAddrTestfunc(t, revel.IPv4, test_ipv4_ipaddrs, "invalid (%s) IPv4 address")
378         runIPAddrTestfunc(t, revel.IPv4CIDR, test_ipv4_with_cidr_ipaddrs, "invalid (%s) IPv4 with CIDR address")
379
380         runIPAddrTestfunc(t, revel.IPv6, test_ipv6_ipaddrs, "invalid (%s) IPv6 address")
381         runIPAddrTestfunc(t, revel.IPv6CIDR, test_ipv6_with_cidr_ipaddrs, "invalid (%s) IPv6 with CIDR address")
382         runIPAddrTestfunc(t, revel.IPv4MappedIPv6, test_ipv4_mapped_ipv6_ipaddrs, "invalid (%s) IPv4-Mapped Embedded IPv6 address")
383 }
384
385 func TestMacAddr(t *testing.T) {
386
387         macaddr_list := map[string]bool{
388                 "02:f3:71:eb:9e:4b": true,
389                 "02-f3-71-eb-9e-4b": true,
390                 "02f3.71eb.9e4b":    true,
391                 "87:78:6e:3e:90:40": true,
392                 "87-78-6e-3e-90-40": true,
393                 "8778.6e3e.9040":    true,
394                 "e7:28:b9:57:ab:36": true,
395                 "e7-28-b9-57-ab-36": true,
396                 "e728.b957.ab36":    true,
397                 "eb:f8:2b:d7:e9:62": true,
398                 "eb-f8-2b-d7-e9-62": true,
399                 "ebf8.2bd7.e962":    true,
400         }
401
402         test_macaddr_list := []Expect{}
403         for macaddr, expected := range macaddr_list {
404                 test_macaddr_list = append(test_macaddr_list, Expect{input: macaddr, expectedResult: expected, errorMessage: fmt.Sprintf("invalid (%s) MAC address", macaddr)})
405         }
406
407         for _, mac_test_list := range []revel.MacAddr{{}, revel.ValidMacAddr()} {
408                 performTests(mac_test_list, test_macaddr_list, t)
409         }
410 }
411
412 func TestDomain(t *testing.T) {
413
414         test_domains := map[string]bool{
415                 "대한민국.xn-korea.co.kr":           true,
416                 "google.com":                    true,
417                 "masełkowski.pl":                true,
418                 "maselkowski.pl":                true,
419                 "m.maselkowski.pl":              true,
420                 "www.masełkowski.pl.com":        true,
421                 "xn--masekowski-d0b.pl":         true,
422                 "中国互联网络信息中心.中国":                 true,
423                 "masełkowski.pl.":               false,
424                 "中国互联网络信息中心.xn--masekowski-d0b": false,
425                 "a.jp":                     true,
426                 "a.co":                     true,
427                 "a.co.jp":                  true,
428                 "a.co.or":                  true,
429                 "a.or.kr":                  true,
430                 "qwd-qwdqwd.com":           true,
431                 "qwd-qwdqwd.co_m":          false,
432                 "qwd-qwdqwd.c":             false,
433                 "qwd-qwdqwd.-12":           false,
434                 "qwd-qwdqwd.1212":          false,
435                 "qwd-qwdqwd.org":           true,
436                 "qwd-qwdqwd.ac.kr":         true,
437                 "qwd-qwdqwd.gov":           true,
438                 "chicken.beer":             true,
439                 "aa.xyz":                   true,
440                 "google.asn.au":            true,
441                 "google.com.au":            true,
442                 "google.net.au":            true,
443                 "google.priv.at":           true,
444                 "google.ac.at":             true,
445                 "google.gv.at":             true,
446                 "google.avocat.fr":         true,
447                 "google.geek.nz":           true,
448                 "google.gen.nz":            true,
449                 "google.kiwi.nz":           true,
450                 "google.org.il":            true,
451                 "google.net.il":            true,
452                 "www.google.edu.au":        true,
453                 "www.google.gov.au":        true,
454                 "www.google.csiro.au":      true,
455                 "www.google.act.au":        true,
456                 "www.google.avocat.fr":     true,
457                 "www.google.aeroport.fr":   true,
458                 "www.google.co.nz":         true,
459                 "www.google.geek.nz":       true,
460                 "www.google.gen.nz":        true,
461                 "www.google.kiwi.nz":       true,
462                 "www.google.parliament.nz": true,
463                 "www.google.muni.il":       true,
464                 "www.google.idf.il":        true,
465         }
466
467         tests := []Expect{}
468
469         for domain, expected := range test_domains {
470                 tests = append(tests, Expect{input: domain, expectedResult: expected, errorMessage: fmt.Sprintf("invalid (%s) domain", domain)})
471         }
472
473         for _, domain := range []revel.Domain{{}, revel.ValidDomain()} {
474                 performTests(domain, tests, t)
475         }
476 }
477
478 func TestURL(t *testing.T) {
479
480         test_urls := map[string]bool{
481                 "https://www.google.co.kr/url?sa=t&rct=j&q=&esrc=s&source=web":                                      true,
482                 "http://stackoverflow.com/questions/27812164/can-i-import-3rd-party-package-into-golang-playground": true,
483                 "https://tour.golang.org/welcome/4":                                                                 true,
484                 "https://revel.github.io/":                                                                          true,
485                 "https://github.com/revel/revel/commit/bd1d083ee4345e919b3bca1e4c42ca682525e395#diff-972a2b2141d27e9d7a8a4149a7e28eef": true,
486                 "https://github.com/ndevilla/iniparser/pull/82#issuecomment-261817064":                                                 true,
487                 "http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=golang":                                            true,
488                 "http://www.baidu.com/link?url=DrWkM_beo2M5kB5sLYnItKSQ0Ib3oDhKcPprdtLzAWNfFt_VN5oyD3KwnAKT6Xsk":                       true,
489         }
490
491         tests := []Expect{}
492
493         for url, expected := range test_urls {
494                 tests = append(tests, Expect{input: url, expectedResult: expected, errorMessage: fmt.Sprintf("invalid (%s) url", url)})
495         }
496
497         for _, url := range []revel.URL{{}, revel.ValidURL()} {
498                 performTests(url, tests, t)
499         }
500
501 }
502
503 func TestPureTextNormal(t *testing.T) {
504
505         test_txts := map[string]bool{
506                 `<script ?>qwdpijqwd</script>qd08j123lneqw\t\nqwedojiqwd\rqwdoihjqwd1d[08jaedl;jkqwd\r\nqdolijqdwqwd`:       false,
507                 `a\r\nb<script ?>qwdpijqwd</script>qd08j123lneqw\t\nqwedojiqwd\rqwdoihjqwd1d[08jaedl;jkqwd\r\nqdolijqdwqwd`: false,
508                 `Foo<script type="text/javascript">alert(1337)</script>Bar`:                                                 false,
509                 `Foo<12>Bar`:              true,
510                 `Foo<>Bar`:                true,
511                 `Foo</br>Bar`:             false,
512                 `Foo <!-- Bar --> Baz`:    false,
513                 `I <3 Ponies!`:            true,
514                 `I &#32; like Golang\t\n`: true,
515                 `I &amp; like Golang\t\n`: false,
516                 `<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration debug="true" xmlns:log4j='http://jakarta.apache.org/log4j/'> <appender name="console" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" /> </layout> </appender> <root> <level value="DEBUG" /> <appender-ref ref="console" /> </root> </log4j:configuration>`: false,
517                 `I like Golang\r\n`:       true,
518                 `I like Golang\r\na`:      true,
519                 "I &#32; like Golang\t\n": true,
520                 "I &amp; like Golang\t\n": false,
521                 `ハイレゾ対応ウォークマン®、ヘッドホン、スピーカー「Winter Gift Collection ~Presented by JUJU~」をソニーストアにて販売開始`:                                                                      true,
522                 `VAIOパーソナルコンピューター type T TZシリーズ 無償点検・修理のお知らせとお詫び(2009年10月15日更新)`:                                                                                          true,
523                 `把百度设为主页关于百度About  Baidu百度推广`:                                                                                                                             true,
524                 `%E6%8A%8A%E7%99%BE%E5%BA%A6%E8%AE%BE%E4%B8%BA%E4%B8%BB%E9%A1%B5%E5%85%B3%E4%BA%8E%E7%99%BE%E5%BA%A6About++Baidu%E7%99%BE%E5%BA%A6%E6%8E%A8%E5%B9%BF`:     true,
525                 `%E6%8A%8A%E7%99%BE%E5%BA%A6%E8%AE%BE%E4%B8%BA%E4%B8%BB%E9%A1%B5%E5%85%B3%E4%BA%8E%E7%99%BE%E5%BA%A6About%20%20Baidu%E7%99%BE%E5%BA%A6%E6%8E%A8%E5%B9%BF`: true,
526                 `abcd/>qwdqwdoijhwer/>qwdojiqwdqwd</>qwdoijqwdoiqjd`:                                                                                                      true,
527                 `abcd/>qwdqwdoijhwer/>qwdojiqwdqwd</a>qwdoijqwdoiqjd`:                                                                                                     false,
528         }
529
530         tests := []Expect{}
531
532         for txt, expected := range test_txts {
533                 tests = append(tests, Expect{input: txt, expectedResult: expected, errorMessage: fmt.Sprintf("invalid (%#v) text", txt)})
534         }
535
536         // normal
537         for _, txt := range []revel.PureText{{revel.NORMAL}, revel.ValidPureText(revel.NORMAL)} {
538                 performTests(txt, tests, t)
539         }
540 }
541
542 func TestPureTextStrict(t *testing.T) {
543
544         test_txts := map[string]bool{
545                 `<script ?>qwdpijqwd</script>qd08j123lneqw\t\nqwedojiqwd\rqwdoihjqwd1d[08jaedl;jkqwd\r\nqdolijqdwqwd`:       false,
546                 `a\r\nb<script ?>qwdpijqwd</script>qd08j123lneqw\t\nqwedojiqwd\rqwdoihjqwd1d[08jaedl;jkqwd\r\nqdolijqdwqwd`: false,
547                 `Foo<script type="text/javascript">alert(1337)</script>Bar`:                                                 false,
548                 `Foo<12>Bar`:              true,
549                 `Foo<>Bar`:                true,
550                 `Foo</br>Bar`:             false,
551                 `Foo <!-- Bar --> Baz`:    false,
552                 `I <3 Ponies!`:            true,
553                 `I &#32; like Golang\t\n`: true,
554                 `I &amp; like Golang\t\n`: false,
555                 `<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration debug="true" xmlns:log4j='http://jakarta.apache.org/log4j/'> <ender name="console" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p 1}:%L - %m%n" /> </layout> </appender> <root> <level value="DEBUG" /> <appender-ref ref="console" /> </root> </log4j:configuration>`: false,
556                 `I like Golang\r\n`:       true,
557                 `I like Golang\r\na`:      true,
558                 "I &#32; like Golang\t\n": true,
559                 "I &amp; like Golang\t\n": false,
560                 `ハイレゾ対応ウォークマン®、ヘッドホン、スピーカー「Winter Gift Collection ~Presented by JUJU~」をソニーストアにて販売開始`:                                                                      true,
561                 `VAIOパーソナルコンピューター type T TZシリーズ 無償点検・修理のお知らせとお詫び(2009年10月15日更新)`:                                                                                          true,
562                 `把百度设为主页关于百度About  Baidu百度推广`:                                                                                                                             true,
563                 `%E6%8A%8A%E7%99%BE%E5%BA%A6%E8%AE%BE%E4%B8%BA%E4%B8%BB%E9%A1%B5%E5%85%B3%E4%BA%8E%E7%99%BE%E5%BA%A6About++Baidu%E7%99%BE%E5%BA%A6%E6%8E%A8%E5%B9%BF`:     true,
564                 `%E6%8A%8A%E7%99%BE%E5%BA%A6%E8%AE%BE%E4%B8%BA%E4%B8%BB%E9%A1%B5%E5%85%B3%E4%BA%8E%E7%99%BE%E5%BA%A6About%20%20Baidu%E7%99%BE%E5%BA%A6%E6%8E%A8%E5%B9%BF`: true,
565                 `abcd/>qwdqwdoijhwer/>qwdojiqwdqwd</>qwdoijqwdoiqjd`:                                                                                                      true,
566                 `abcd/>qwdqwdoijhwer/>qwdojiqwdqwd</a>qwdoijqwdoiqjd`:                                                                                                     false,
567         }
568
569         tests := []Expect{}
570
571         for txt, expected := range test_txts {
572                 tests = append(tests, Expect{input: txt, expectedResult: expected, errorMessage: fmt.Sprintf("invalid (%#v) text", txt)})
573         }
574
575         // strict
576         for _, txt := range []revel.PureText{{revel.STRICT}, revel.ValidPureText(revel.STRICT)} {
577                 performTests(txt, tests, t)
578         }
579 }
580
581 func TestFilePathOnlyFilePath(t *testing.T) {
582
583         test_filepaths := map[string]bool{
584                 "../../qwdqwdqwd/../qwdqwdqwd.txt": false,
585                 `../../qwdqwdqwd/..
586                                         /qwdqwdqwd.txt`: false,
587                 "\t../../qwdqwdqwd/../qwdqwdqwd.txt": false,
588                 `\16../../qwdqwdqwd/../qwdqwdqwd.txt`: false,
589                 `../../qwdqwdqwd/..\ 2/qwdqwdqwd.txt`: false,
590                 "../../etc/passwd":                 false,
591                 "a.txt;rm -rf /":                   false,
592                 "sudo rm -rf ../":                  false,
593                 "a-1-s-d-v-we-wd_+qwd-qwd-qwd.txt": false,
594                 "a-qwdqwd_qwdqwdqwd-123.txt":       true,
595                 "a.txt": true,
596                 "a-1-e-r-t-_1_21234_d_1234_qwed_1423_.txt": true,
597         }
598
599         tests := []Expect{}
600
601         for filepath, expected := range test_filepaths {
602                 tests = append(tests, Expect{input: filepath, expectedResult: expected, errorMessage: fmt.Sprintf("unsanitary (%#v) string", filepath)})
603         }
604
605         // filename without relative path
606         for _, filepath := range []revel.FilePath{{revel.ONLY_FILENAME}, revel.ValidFilePath(revel.ONLY_FILENAME)} {
607                 performTests(filepath, tests, t)
608         }
609 }
610
611 func TestFilePathAllowRelativePath(t *testing.T) {
612
613         test_filepaths := map[string]bool{
614                 "../../qwdqwdqwd/../qwdqwdqwd.txt": true,
615                 `../../qwdqwdqwd/..
616                                         /qwdqwdqwd.txt`: false,
617                 "\t../../qwdqwdqwd/../qwdqwdqwd.txt": false,
618                 `\16../../qwdqwdqwd/../qwdqwdqwd.txt`: false,
619                 `../../qwdqwdqwd/..\ 2/qwdqwdqwd.txt`: false,
620                 "../../etc/passwd":                 true,
621                 "a.txt;rm -rf /":                   false,
622                 "sudo rm -rf ../":                  true,
623                 "a-1-s-d-v-we-wd_+qwd-qwd-qwd.txt": false,
624                 "a-qwdqwd_qwdqwdqwd-123.txt":       true,
625                 "a.txt": true,
626                 "a-1-e-r-t-_1_21234_d_1234_qwed_1423_.txt":                                       true,
627                 "/asdasd/asdasdasd/qwdqwd_qwdqwd/12-12/a-1-e-r-t-_1_21234_d_1234_qwed_1423_.txt": true,
628         }
629
630         tests := []Expect{}
631
632         for filepath, expected := range test_filepaths {
633                 tests = append(tests, Expect{input: filepath, expectedResult: expected, errorMessage: fmt.Sprintf("unsanitary (%#v) string", filepath)})
634         }
635
636         // filename with relative path
637         for _, filepath := range []revel.FilePath{{revel.ALLOW_RELATIVE_PATH}, revel.ValidFilePath(revel.ALLOW_RELATIVE_PATH)} {
638                 performTests(filepath, tests, t)
639         }
640 }