This repository has been archived by the owner on Sep 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
httpfake.go
150 lines (114 loc) · 3.32 KB
/
httpfake.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package go_httpfake
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
)
// RequestResponse is the structure where routes are saving
type RequestResponse struct {
returnStatus int
returnBody string
returnHeaders map[string]string
requestParams map[string]string
}
// HTTPFake is the workhorse used to add, delete routes and to start a fake server
type HTTPFake struct {
started bool
server *httptest.Server
routes map[string]map[string]RequestResponse
}
// New return an instance of HTTPFake
func New() *HTTPFake {
return &HTTPFake{started: false}
}
// AddRoute is using to add a new route
func (h *HTTPFake) AddRoute(route string, method string, requestParams map[string]string, returnStatus int, returnBody string, returnHeaders map[string]string) bool {
if h.started {
return false
}
if len(h.routes) == 0 {
h.routes = map[string]map[string]RequestResponse{}
}
if _, ok := h.routes[route]; !ok {
h.routes[route] = map[string]RequestResponse{}
}
h.routes[route][method] = RequestResponse{
returnStatus: returnStatus,
returnBody: returnBody,
returnHeaders: returnHeaders,
requestParams: requestParams,
}
return true
}
// DelRoute is using to delete a route
func (h *HTTPFake) DelRoute(route string, method string) bool {
if h.started {
return false
}
if _, ok := h.routes[route]; !ok {
return false
}
if _, ok := h.routes[route][method]; !ok {
return false
}
delete(h.routes[route], method)
if len(h.routes[route]) == 0 {
delete(h.routes, route)
}
return true
}
// Start is using to start a new fake server
func (h *HTTPFake) Start() *httptest.Server {
h.started = true
h.server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
route := strings.Replace(r.URL.String(), "/", "", 1)
if _, ok := h.routes[route]; !ok {
h.notFound(w, map[string]string{})
return
}
if _, ok := h.routes[route][r.Method]; !ok {
h.notFound(w, map[string]string{})
return
}
requestResponse := h.routes[route][r.Method]
// Convert body parameters to map
contents, err := ioutil.ReadAll(r.Body)
if err != nil {
h.setResponse(w, 500, fmt.Sprintf(`{"error": "%s"}`, err.Error()), requestResponse.returnHeaders)
return
}
var jsonParams map[string]interface{}
_ = json.Unmarshal(contents, &jsonParams)
// Check if expected parameters are in form or body
for key, expectedValue := range requestResponse.requestParams {
jsonParamVal, _ := jsonParams[key]
if r.FormValue(key) != expectedValue && jsonParamVal != expectedValue {
h.notFound(w, requestResponse.returnHeaders)
return
}
}
h.setResponse(w, requestResponse.returnStatus, requestResponse.returnBody, requestResponse.returnHeaders)
}))
return h.server
}
// Close is using to close a fake server
func (h *HTTPFake) Close() {
h.started = false
h.server.Close()
}
func (h *HTTPFake) notFound(w http.ResponseWriter, headers map[string]string) {
h.setResponse(w, 404, `{"error":"Not Found"}`, headers)
}
func (h *HTTPFake) setResponse(w http.ResponseWriter, status int, body string, headers map[string]string) {
h.addHeaders(w, headers)
w.WriteHeader(status)
w.Write([]byte(body))
}
func (h *HTTPFake) addHeaders(w http.ResponseWriter, headers map[string]string) {
for key, value := range headers {
w.Header().Add(key, value)
}
}