NewMockedHTTPClient creates a new HTTP client that registers a handler for /graphql POST requests. For each request, an attempt will be be made to match the request body against the provided matchers. If a match is found, the corresponding response will be returned with StatusOK. Note that query an
(ms ...Matcher)
| 149 | // This client does not currently provide a mechanism for out-of-band errors e.g. returning a 500, |
| 150 | // and errors are constrained to GQL errors returned in the response body with a 200 status code. |
| 151 | func NewMockedHTTPClient(ms ...Matcher) *http.Client { |
| 152 | matchers := make(map[string]Matcher, len(ms)) |
| 153 | for _, m := range ms { |
| 154 | matchers[m.Request] = m |
| 155 | } |
| 156 | |
| 157 | mux := http.NewServeMux() |
| 158 | mux.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) { |
| 159 | if r.Method != http.MethodPost { |
| 160 | http.Error(w, "method not allowed", http.StatusMethodNotAllowed) |
| 161 | return |
| 162 | } |
| 163 | |
| 164 | gqlRequest, err := parseBody(r.Body) |
| 165 | if err != nil { |
| 166 | http.Error(w, "invalid request body", http.StatusBadRequest) |
| 167 | return |
| 168 | } |
| 169 | defer func() { _ = r.Body.Close() }() |
| 170 | |
| 171 | matcher, ok := matchers[gqlRequest.Query] |
| 172 | if !ok { |
| 173 | http.Error(w, fmt.Sprintf("no matcher found for query %s", gqlRequest.Query), http.StatusNotFound) |
| 174 | return |
| 175 | } |
| 176 | |
| 177 | if len(gqlRequest.Variables) > 0 { |
| 178 | if len(gqlRequest.Variables) != len(matcher.Variables) { |
| 179 | http.Error(w, "variables do not have the same length", http.StatusBadRequest) |
| 180 | return |
| 181 | } |
| 182 | |
| 183 | for k, v := range matcher.Variables { |
| 184 | if !objectsAreEqualValues(v, gqlRequest.Variables[k]) { |
| 185 | http.Error(w, "variable does not match", http.StatusBadRequest) |
| 186 | return |
| 187 | } |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | responseBody, err := json.Marshal(matcher.Response) |
| 192 | if err != nil { |
| 193 | http.Error(w, "error marshalling response", http.StatusInternalServerError) |
| 194 | return |
| 195 | } |
| 196 | |
| 197 | w.Header().Set("Content-Type", "application/json") |
| 198 | w.WriteHeader(http.StatusOK) |
| 199 | _, _ = w.Write(responseBody) |
| 200 | }) |
| 201 | |
| 202 | return &http.Client{Transport: &localRoundTripper{ |
| 203 | handler: mux, |
| 204 | }} |
| 205 | } |
| 206 | |
| 207 | type gqlRequest struct { |
| 208 | Query string `json:"query"` |