|
2 | 2 | import requests
|
3 | 3 | from httmock import HTTMock, response, urlmatch
|
4 | 4 |
|
5 |
| -from gitlab import GitlabHttpError, GitlabList, GitlabParsingError |
| 5 | +from gitlab import GitlabHttpError, GitlabList, GitlabParsingError, RedirectError |
6 | 6 |
|
7 | 7 |
|
8 | 8 | def test_build_url(gl):
|
@@ -123,9 +123,96 @@ def resp_cont(url, request):
|
123 | 123 | assert call_count == 1
|
124 | 124 |
|
125 | 125 |
|
| 126 | +def create_redirect_response( |
| 127 | + *, request: requests.models.PreparedRequest, http_method: str, api_path: str |
| 128 | +) -> requests.models.Response: |
| 129 | + """Create a Requests response object that has a redirect in it""" |
| 130 | + |
| 131 | + assert api_path.startswith("/") |
| 132 | + http_method = http_method.upper() |
| 133 | + |
| 134 | + # Create a history which contains our original request which is redirected |
| 135 | + history = [ |
| 136 | + response( |
| 137 | + status_code=302, |
| 138 | + content="", |
| 139 | + headers={"Location": f"http://example.com/api/v4{api_path}"}, |
| 140 | + reason="Moved Temporarily", |
| 141 | + request=request, |
| 142 | + ) |
| 143 | + ] |
| 144 | + |
| 145 | + # Create a "prepped" Request object to be the final redirect. The redirect |
| 146 | + # will be a "GET" method as Requests changes the method to "GET" when there |
| 147 | + # is a 301/302 redirect code. |
| 148 | + req = requests.Request( |
| 149 | + method="GET", |
| 150 | + url=f"http://example.com/api/v4{api_path}", |
| 151 | + ) |
| 152 | + prepped = req.prepare() |
| 153 | + |
| 154 | + resp_obj = response( |
| 155 | + status_code=200, |
| 156 | + content="", |
| 157 | + headers={}, |
| 158 | + reason="OK", |
| 159 | + elapsed=5, |
| 160 | + request=prepped, |
| 161 | + ) |
| 162 | + resp_obj.history = history |
| 163 | + return resp_obj |
| 164 | + |
| 165 | + |
| 166 | +def test_http_request_302_get_does_not_raise(gl): |
| 167 | + """Test to show that a redirect of a GET will not cause an error""" |
| 168 | + |
| 169 | + method = "get" |
| 170 | + api_path = "/user/status" |
| 171 | + |
| 172 | + @urlmatch( |
| 173 | + scheme="http", netloc="localhost", path=f"/api/v4{api_path}", method=method |
| 174 | + ) |
| 175 | + def resp_cont( |
| 176 | + url: str, request: requests.models.PreparedRequest |
| 177 | + ) -> requests.models.Response: |
| 178 | + resp_obj = create_redirect_response( |
| 179 | + request=request, http_method=method, api_path=api_path |
| 180 | + ) |
| 181 | + return resp_obj |
| 182 | + |
| 183 | + with HTTMock(resp_cont): |
| 184 | + gl.http_request(verb=method, path=api_path) |
| 185 | + |
| 186 | + |
| 187 | +def test_http_request_302_put_raises_redirect_error(gl): |
| 188 | + """Test to show that a redirect of a PUT will cause an error""" |
| 189 | + |
| 190 | + method = "put" |
| 191 | + api_path = "/user/status" |
| 192 | + |
| 193 | + @urlmatch( |
| 194 | + scheme="http", netloc="localhost", path=f"/api/v4{api_path}", method=method |
| 195 | + ) |
| 196 | + def resp_cont( |
| 197 | + url: str, request: requests.models.PreparedRequest |
| 198 | + ) -> requests.models.Response: |
| 199 | + resp_obj = create_redirect_response( |
| 200 | + request=request, http_method=method, api_path=api_path |
| 201 | + ) |
| 202 | + return resp_obj |
| 203 | + |
| 204 | + with HTTMock(resp_cont): |
| 205 | + with pytest.raises(RedirectError) as exc: |
| 206 | + gl.http_request(verb=method, path=api_path) |
| 207 | + error_message = exc.value.error_message |
| 208 | + assert "Moved Temporarily" in error_message |
| 209 | + assert "http://localhost/api/v4/user/status" in error_message |
| 210 | + assert "http://example.com/api/v4/user/status" in error_message |
| 211 | + |
| 212 | + |
126 | 213 | def test_get_request(gl):
|
127 | 214 | @urlmatch(scheme="http", netloc="localhost", path="/api/v4/projects", method="get")
|
128 |
| - def resp_cont(url, request): |
| 215 | + def resp_cont(url: str, request: requests.models.PreparedRequest): |
129 | 216 | headers = {"content-type": "application/json"}
|
130 | 217 | content = '{"name": "project1"}'
|
131 | 218 | return response(200, content, headers, None, 5, request)
|
|
0 commit comments