1package mocks
2
3// Copyright 2017 Microsoft Corporation
4//
5//  Licensed under the Apache License, Version 2.0 (the "License");
6//  you may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at
8//
9//      http://www.apache.org/licenses/LICENSE-2.0
10//
11//  Unless required by applicable law or agreed to in writing, software
12//  distributed under the License is distributed on an "AS IS" BASIS,
13//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14//  See the License for the specific language governing permissions and
15//  limitations under the License.
16
17import (
18	"fmt"
19	"io"
20	"net/http"
21	"time"
22)
23
24const (
25	// TestAuthorizationHeader is a faux HTTP Authorization header value
26	TestAuthorizationHeader = "BEARER SECRETTOKEN"
27
28	// TestBadURL is a malformed URL
29	TestBadURL = "                               "
30
31	// TestDelay is the Retry-After delay used in tests.
32	TestDelay = 0 * time.Second
33
34	// TestHeader is the header used in tests.
35	TestHeader = "x-test-header"
36
37	// TestURL is the URL used in tests.
38	TestURL = "https://microsoft.com/a/b/c/"
39
40	// TestAzureAsyncURL is a URL used in Azure asynchronous tests
41	TestAzureAsyncURL = "https://microsoft.com/a/b/c/async"
42
43	// TestLocationURL is a URL used in Azure asynchronous tests
44	TestLocationURL = "https://microsoft.com/a/b/c/location"
45)
46
47const (
48	headerLocation   = "Location"
49	headerRetryAfter = "Retry-After"
50)
51
52// NewRequest instantiates a new request.
53func NewRequest() *http.Request {
54	return NewRequestWithContent("")
55}
56
57// NewRequestWithContent instantiates a new request using the passed string for the body content.
58func NewRequestWithContent(c string) *http.Request {
59	r, _ := http.NewRequest("GET", "https://microsoft.com/a/b/c/", NewBody(c))
60	return r
61}
62
63// NewRequestWithCloseBody instantiates a new request.
64func NewRequestWithCloseBody() *http.Request {
65	return NewRequestWithCloseBodyContent("request body")
66}
67
68// NewRequestWithCloseBodyContent instantiates a new request using the passed string for the body content.
69func NewRequestWithCloseBodyContent(c string) *http.Request {
70	r, _ := http.NewRequest("GET", "https://microsoft.com/a/b/c/", NewBodyClose(c))
71	return r
72}
73
74// NewRequestForURL instantiates a new request using the passed URL.
75func NewRequestForURL(u string) *http.Request {
76	return NewRequestWithParams("GET", u, NewBody(""))
77}
78
79// NewRequestWithParams instantiates a new request using the provided parameters.
80func NewRequestWithParams(method, u string, body io.Reader) *http.Request {
81	r, err := http.NewRequest(method, u, body)
82	if err != nil {
83		panic(fmt.Sprintf("mocks: ERROR (%v) parsing testing URL %s", err, u))
84	}
85	return r
86}
87
88// NewResponse instantiates a new response.
89func NewResponse() *http.Response {
90	return NewResponseWithContent("")
91}
92
93// NewResponseWithContent instantiates a new response with the passed string as the body content.
94func NewResponseWithContent(c string) *http.Response {
95	return &http.Response{
96		Status:     "200 OK",
97		StatusCode: 200,
98		Proto:      "HTTP/1.0",
99		ProtoMajor: 1,
100		ProtoMinor: 0,
101		Body:       NewBody(c),
102		Request:    NewRequest(),
103	}
104}
105
106// NewResponseWithStatus instantiates a new response using the passed string and integer as the
107// status and status code.
108func NewResponseWithStatus(s string, c int) *http.Response {
109	resp := NewResponse()
110	resp.Status = s
111	resp.StatusCode = c
112	return resp
113}
114
115// NewResponseWithBodyAndStatus instantiates a new response using the specified mock body,
116// status and status code
117func NewResponseWithBodyAndStatus(body *Body, c int, s string) *http.Response {
118	resp := NewResponse()
119	resp.Body = body
120	resp.ContentLength = body.Length()
121	resp.Status = s
122	resp.StatusCode = c
123	return resp
124}
125
126// SetResponseHeader adds a header to the passed response.
127func SetResponseHeader(resp *http.Response, h string, v string) {
128	if resp.Header == nil {
129		resp.Header = make(http.Header)
130	}
131	resp.Header.Set(h, v)
132}
133
134// SetResponseHeaderValues adds a header containing all the passed string values.
135func SetResponseHeaderValues(resp *http.Response, h string, values []string) {
136	if resp.Header == nil {
137		resp.Header = make(http.Header)
138	}
139	for _, v := range values {
140		resp.Header.Add(h, v)
141	}
142}
143
144// SetAcceptedHeaders adds the headers usually associated with a 202 Accepted response.
145func SetAcceptedHeaders(resp *http.Response) {
146	SetLocationHeader(resp, TestURL)
147	SetRetryHeader(resp, TestDelay)
148}
149
150// SetLocationHeader adds the Location header.
151func SetLocationHeader(resp *http.Response, location string) {
152	SetResponseHeader(resp, http.CanonicalHeaderKey(headerLocation), location)
153}
154
155// SetRetryHeader adds the Retry-After header.
156func SetRetryHeader(resp *http.Response, delay time.Duration) {
157	SetResponseHeader(resp, http.CanonicalHeaderKey(headerRetryAfter), fmt.Sprintf("%v", delay.Seconds()))
158}
159