OLD | NEW |
| (Empty) |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package epfrontend | |
6 | |
7 import ( | |
8 "bytes" | |
9 "errors" | |
10 "net/http" | |
11 "strings" | |
12 "testing" | |
13 | |
14 . "github.com/smartystreets/goconvey/convey" | |
15 ) | |
16 | |
17 type testResponseWriter struct { | |
18 status int | |
19 data bytes.Buffer | |
20 err error | |
21 header http.Header | |
22 } | |
23 | |
24 func (w *testResponseWriter) Header() http.Header { | |
25 return w.header | |
26 } | |
27 | |
28 func (w *testResponseWriter) WriteHeader(status int) { | |
29 w.status = status | |
30 } | |
31 | |
32 func (w *testResponseWriter) Write(d []byte) (int, error) { | |
33 if w.err != nil { | |
34 return 0, w.err | |
35 } | |
36 return w.data.Write(d) | |
37 } | |
38 | |
39 func TestErrorResponseWriter(t *testing.T) { | |
40 Convey(`An errorResponseWriter bound to a testing ResponseWriter`, t, fu
nc() { | |
41 rw := &testResponseWriter{} | |
42 erw := &errorResponseWriter{ | |
43 ResponseWriter: rw, | |
44 } | |
45 | |
46 Convey(`When no error is encountered, data is written directly.`
, func() { | |
47 erw.WriteHeader(http.StatusOK) | |
48 c, err := erw.Write([]byte("test")) | |
49 So(err, ShouldBeNil) | |
50 So(c, ShouldEqual, 4) | |
51 | |
52 So(rw.status, ShouldEqual, http.StatusOK) | |
53 So(rw.data.String(), ShouldResemble, "test") | |
54 So(erw.forwardError(), ShouldBeFalse) | |
55 }) | |
56 | |
57 Convey(`When an error is encountered, status is translated and d
ata is buffered.`, func() { | |
58 erw.WriteHeader(http.StatusNotAcceptable) // 406 => 404 | |
59 c, err := erw.Write([]byte("{}")) | |
60 So(err, ShouldBeNil) | |
61 So(c, ShouldEqual, 2) | |
62 | |
63 So(rw.status, ShouldEqual, http.StatusNotFound) // (404) | |
64 So(rw.data.String(), ShouldEqual, "") | |
65 }) | |
66 | |
67 Convey(`All HTTP error codes translate to error codes.`, func()
{ | |
68 for _, r := range []struct { | |
69 lb int | |
70 ub int | |
71 }{ | |
72 // 400s | |
73 {http.StatusBadRequest, http.StatusTeapot}, | |
74 | |
75 // 500s | |
76 {http.StatusInternalServerError, http.StatusHTTP
VersionNotSupported}, | |
77 | |
78 // Not real error code. | |
79 {1024, 1024}, | |
80 } { | |
81 for i := r.lb; i <= r.ub; i++ { | |
82 r, inst := erw.translateReason(i) | |
83 So(r, ShouldBeGreaterThanOrEqualTo, http
.StatusBadRequest) | |
84 So(inst, ShouldNotBeNil) | |
85 | |
86 So(inst.Domain, ShouldEqual, "global") | |
87 So(inst.Reason, ShouldNotEqual, "") | |
88 } | |
89 } | |
90 }) | |
91 | |
92 Convey(`An error set by the frontend is forwarded.`, func() { | |
93 erw.setError(errors.New("test error")) | |
94 So(erw.forwardError(), ShouldBeTrue) | |
95 | |
96 So(rw.status, ShouldEqual, http.StatusServiceUnavailable
) | |
97 So(rw.data.String(), ShouldEqual, strings.Join([]string{ | |
98 `{`, | |
99 ` "error": {`, | |
100 ` "code": 503,`, | |
101 ` "errors": [`, | |
102 ` {`, | |
103 ` "domain": "global",`, | |
104 ` "message": "test error",`, | |
105 ` "reason": "backendError"`, | |
106 ` }`, | |
107 ` ],`, | |
108 ` "message": "unspecified error"`, | |
109 ` }`, | |
110 `}`, | |
111 }, "\n")) | |
112 }) | |
113 | |
114 Convey(`A valid error set by the backend is forwarded.`, func()
{ | |
115 erw.WriteHeader(http.StatusNotFound) | |
116 _, err := erw.Write([]byte(`{"state": "APPLICATION_ERROR
", "error_message": "test error"}`)) | |
117 So(err, ShouldBeNil) | |
118 So(erw.forwardError(), ShouldBeTrue) | |
119 | |
120 So(rw.status, ShouldEqual, http.StatusNotFound) | |
121 So(rw.data.String(), ShouldEqual, strings.Join([]string{ | |
122 `{`, | |
123 ` "error": {`, | |
124 ` "code": 404,`, | |
125 ` "errors": [`, | |
126 ` {`, | |
127 ` "domain": "global",`, | |
128 ` "message": "test error",`, | |
129 ` "reason": "notFound"`, | |
130 ` }`, | |
131 ` ],`, | |
132 ` "message": "test error"`, | |
133 ` }`, | |
134 `}`, | |
135 }, "\n")) | |
136 }) | |
137 | |
138 Convey(`An invalid error set by the backend is forwarded.`, func
() { | |
139 erw.WriteHeader(http.StatusNotFound) | |
140 _, err := erw.Write([]byte(`DEFINITELY NOT JSON`)) | |
141 So(err, ShouldBeNil) | |
142 So(erw.forwardError(), ShouldBeTrue) | |
143 | |
144 So(rw.status, ShouldEqual, http.StatusNotFound) | |
145 So(rw.data.String(), ShouldEqual, strings.Join([]string{ | |
146 `{`, | |
147 ` "error": {`, | |
148 ` "code": 404,`, | |
149 ` "errors": [`, | |
150 ` {`, | |
151 ` "domain": "global",`, | |
152 ` "message": "Failed to decode error JSON (in
valid character 'D' looking for beginning of value): ",`, | |
153 ` "reason": "notFound"`, | |
154 ` }`, | |
155 ` ],`, | |
156 ` "message": "unspecified error"`, | |
157 ` }`, | |
158 `}`, | |
159 }, "\n")) | |
160 }) | |
161 }) | |
162 } | |
OLD | NEW |