1
2
3
4
5
6
7
8
9
10
11
12
13 package chttp
14
15 import (
16 "net/http"
17 "testing"
18
19 "gitlab.com/flimzy/testy"
20
21 internal "github.com/go-kivik/kivik/v4/int/errors"
22 )
23
24 func TestHTTPErrorError(t *testing.T) {
25 tests := []struct {
26 name string
27 input *HTTPError
28 expected string
29 }{
30 {
31 name: "No reason",
32 input: &HTTPError{
33 Response: &http.Response{StatusCode: 400},
34 },
35 expected: "Bad Request",
36 },
37 {
38 name: "Reason, HTTP code",
39 input: &HTTPError{
40 Response: &http.Response{StatusCode: 400},
41 Reason: "Bad stuff",
42 },
43 expected: "Bad Request: Bad stuff",
44 },
45 {
46 name: "Non-HTTP code",
47 input: &HTTPError{
48 Response: &http.Response{StatusCode: 604},
49 Reason: "Bad stuff",
50 },
51 expected: "Bad stuff",
52 },
53 }
54 for _, test := range tests {
55 t.Run(test.name, func(t *testing.T) {
56 result := test.input.Error()
57 if result != test.expected {
58 t.Errorf("Unexpected result: %s", result)
59 }
60 })
61 }
62 }
63
64 func TestResponseError(t *testing.T) {
65 tests := []struct {
66 name string
67 resp *http.Response
68 status int
69 err string
70 expected interface{}
71 }{
72 {
73 name: "non error",
74 resp: &http.Response{StatusCode: 200},
75 expected: nil,
76 },
77 {
78 name: "HEAD error",
79 resp: &http.Response{
80 StatusCode: http.StatusNotFound,
81 Request: &http.Request{Method: "HEAD"},
82 Body: Body(""),
83 },
84 status: http.StatusNotFound,
85 err: "Not Found",
86 expected: &internal.Error{
87 Status: http.StatusNotFound,
88 Err: &HTTPError{
89 Response: &http.Response{
90 StatusCode: http.StatusBadRequest,
91 },
92 },
93 },
94 },
95 {
96 name: "2.0.0 error",
97 resp: &http.Response{
98 StatusCode: http.StatusBadRequest,
99 Header: http.Header{
100 "Cache-Control": {"must-revalidate"},
101 "Content-Length": {"194"},
102 "Content-Type": {"application/json"},
103 "Date": {"Fri, 27 Oct 2017 15:34:07 GMT"},
104 "Server": {"CouchDB/2.0.0 (Erlang OTP/17)"},
105 "X-Couch-Request-ID": {"92d05bd015"},
106 "X-CouchDB-Body-Time": {"0"},
107 },
108 ContentLength: 194,
109 Body: Body(`{"error":"illegal_database_name","reason":"Name: '_foo'. Only lowercase characters (a-z), digits (0-9), and any of the characters _, $, (, ), +, -, and / are allowed. Must begin with a letter."}`),
110 Request: &http.Request{Method: "PUT"},
111 },
112 status: http.StatusBadRequest,
113 err: "Bad Request: Name: '_foo'. Only lowercase characters (a-z), digits (0-9), and any of the characters _, $, (, ), +, -, and / are allowed. Must begin with a letter.",
114 expected: &internal.Error{
115 Status: http.StatusBadRequest,
116 Err: &HTTPError{
117 Response: &http.Response{
118 StatusCode: http.StatusBadRequest,
119 },
120 Reason: "Name: '_foo'. Only lowercase characters (a-z), digits (0-9), and any of the characters _, $, (, ), +, -, and / are allowed. Must begin with a letter.",
121 },
122 },
123 },
124 {
125 name: "invalid json error",
126 resp: &http.Response{
127 StatusCode: http.StatusBadRequest,
128 Header: http.Header{
129 "Server": {"CouchDB/1.6.1 (Erlang OTP/17)"},
130 "Date": {"Fri, 27 Oct 2017 15:42:34 GMT"},
131 "Content-Type": {"application/json"},
132 "Content-Length": {"194"},
133 "Cache-Control": {"must-revalidate"},
134 },
135 ContentLength: 194,
136 Body: Body("invalid json"),
137 Request: &http.Request{Method: "PUT"},
138 },
139 status: http.StatusBadRequest,
140 err: "Bad Request",
141 expected: &internal.Error{
142 Status: http.StatusBadRequest,
143 Err: &HTTPError{
144 Response: &http.Response{
145 StatusCode: http.StatusBadRequest,
146 },
147 },
148 },
149 },
150 }
151 for _, test := range tests {
152 t.Run(test.name, func(t *testing.T) {
153 err := ResponseError(test.resp)
154 if d := internal.StatusErrorDiff(test.err, test.status, err); d != "" {
155 t.Error(d)
156 }
157 if err != nil {
158 return
159 }
160 if he, ok := err.(*HTTPError); ok {
161 he.Response = nil
162 err = he
163 }
164 if d := testy.DiffInterface(test.expected, err); d != nil {
165 t.Error(d)
166 }
167 })
168 }
169 }
170
View as plain text