1# #!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# <HTTPretty - HTTP client mock for Python> 5# Copyright (C) <2011-2021> Gabriel Falcão <gabriel@nacaolivre.org> 6# 7# Permission is hereby granted, free of charge, to any person 8# obtaining a copy of this software and associated documentation 9# files (the "Software"), to deal in the Software without 10# restriction, including without limitation the rights to use, 11# copy, modify, merge, publish, distribute, sublicense, and/or sell 12# copies of the Software, and to permit persons to whom the 13# Software is furnished to do so, subject to the following 14# conditions: 15# 16# The above copyright notice and this permission notice shall be 17# included in all copies or substantial portions of the Software. 18# 19# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26# OTHER DEALINGS IN THE SOFTWARE. 27from __future__ import unicode_literals 28 29import re 30import httplib2 31from freezegun import freeze_time 32from sure import expect, within, miliseconds 33from httpretty import HTTPretty, httprettified 34from httpretty.core import decode_utf8 35 36 37@httprettified 38@within(two=miliseconds) 39def test_httpretty_should_mock_a_simple_get_with_httplib2_read(now): 40 "HTTPretty should mock a simple GET with httplib2.context.http" 41 42 HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/", 43 body="Find the best daily deals") 44 45 _, got = httplib2.Http().request('http://yipit.com', 'GET') 46 expect(got).to.equal(b'Find the best daily deals') 47 48 expect(HTTPretty.last_request.method).to.equal('GET') 49 expect(HTTPretty.last_request.path).to.equal('/') 50 51 52@httprettified 53@within(two=miliseconds) 54def test_httpretty_provides_easy_access_to_querystrings(now): 55 "HTTPretty should provide an easy access to the querystring" 56 57 HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/", 58 body="Find the best daily deals") 59 60 httplib2.Http().request('http://yipit.com?foo=bar&foo=baz&chuck=norris', 'GET') 61 expect(HTTPretty.last_request.querystring).to.equal({ 62 'foo': ['bar', 'baz'], 63 'chuck': ['norris'], 64 }) 65 66 67@httprettified 68@freeze_time("2013-10-04 04:20:00") 69def test_httpretty_should_mock_headers_httplib2(): 70 "HTTPretty should mock basic headers with httplib2" 71 72 HTTPretty.register_uri(HTTPretty.GET, "http://github.com/", 73 body="this is supposed to be the response", 74 status=201) 75 76 headers, _ = httplib2.Http().request('http://github.com', 'GET') 77 expect(headers['status']).to.equal('201') 78 expect(dict(headers)).to.equal({ 79 'content-type': 'text/plain; charset=utf-8', 80 'connection': 'close', 81 'content-length': '35', 82 'status': '201', 83 'server': 'Python/HTTPretty', 84 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', 85 }) 86 87 88@httprettified 89@freeze_time("2013-10-04 04:20:00") 90def test_httpretty_should_allow_adding_and_overwritting_httplib2(): 91 "HTTPretty should allow adding and overwritting headers with httplib2" 92 93 HTTPretty.register_uri(HTTPretty.GET, "http://github.com/foo", 94 body="this is supposed to be the response", 95 adding_headers={ 96 'Server': 'Apache', 97 'Content-Length': '27', 98 'Content-Type': 'application/json', 99 }) 100 101 headers, _ = httplib2.Http().request('http://github.com/foo', 'GET') 102 103 expect(dict(headers)).to.equal({ 104 'content-type': 'application/json', 105 'content-location': 'http://github.com/foo', 106 'connection': 'close', 107 'content-length': '27', 108 'status': '200', 109 'server': 'Apache', 110 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', 111 }) 112 113 114@httprettified 115@within(two=miliseconds) 116def test_httpretty_should_allow_forcing_headers_httplib2(now): 117 "HTTPretty should allow forcing headers with httplib2" 118 119 HTTPretty.register_uri(HTTPretty.GET, "http://github.com/foo", 120 body="this is supposed to be the response", 121 forcing_headers={ 122 'Content-Type': 'application/xml', 123 }) 124 125 headers, _ = httplib2.Http().request('http://github.com/foo', 'GET') 126 127 expect(dict(headers)).to.equal({ 128 'content-location': 'http://github.com/foo', # httplib2 FORCES 129 # content-location 130 # even if the 131 # server does not 132 # provide it 133 'content-type': 'application/xml', 134 'status': '200', # httplib2 also ALWAYS put status on headers 135 }) 136 137 138@httprettified 139@freeze_time("2013-10-04 04:20:00") 140def test_httpretty_should_allow_adding_and_overwritting_by_kwargs_u2(): 141 "HTTPretty should allow adding and overwritting headers by keyword args " \ 142 "with httplib2" 143 144 HTTPretty.register_uri(HTTPretty.GET, "http://github.com/foo", 145 body="this is supposed to be the response", 146 server='Apache', 147 content_length='27', 148 content_type='application/json') 149 150 headers, _ = httplib2.Http().request('http://github.com/foo', 'GET') 151 152 expect(dict(headers)).to.equal({ 153 'content-type': 'application/json', 154 'content-location': 'http://github.com/foo', # httplib2 FORCES 155 # content-location 156 # even if the 157 # server does not 158 # provide it 159 'connection': 'close', 160 'content-length': '27', 161 'status': '200', 162 'server': 'Apache', 163 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', 164 }) 165 166 167@httprettified 168@within(two=miliseconds) 169def test_rotating_responses_with_httplib2(now): 170 "HTTPretty should support rotating responses with httplib2" 171 172 HTTPretty.register_uri( 173 HTTPretty.GET, "https://api.yahoo.com/test", 174 responses=[ 175 HTTPretty.Response(body="first response", status=201), 176 HTTPretty.Response(body='second and last response', status=202), 177 ]) 178 179 headers1, body1 = httplib2.Http().request( 180 'https://api.yahoo.com/test', 'GET') 181 182 expect(headers1['status']).to.equal('201') 183 expect(body1).to.equal(b'first response') 184 185 headers2, body2 = httplib2.Http().request( 186 'https://api.yahoo.com/test', 'GET') 187 188 expect(headers2['status']).to.equal('202') 189 expect(body2).to.equal(b'second and last response') 190 191 headers3, body3 = httplib2.Http().request( 192 'https://api.yahoo.com/test', 'GET') 193 194 expect(headers3['status']).to.equal('202') 195 expect(body3).to.equal(b'second and last response') 196 197 198@httprettified 199@within(two=miliseconds) 200def test_can_inspect_last_request(now): 201 "HTTPretty.last_request is a mimetools.Message request from last match" 202 203 HTTPretty.register_uri(HTTPretty.POST, "http://api.github.com/", 204 body='{"repositories": ["HTTPretty", "lettuce"]}') 205 206 headers, body = httplib2.Http().request( 207 'http://api.github.com', 'POST', 208 body='{"username": "gabrielfalcao"}', 209 headers={ 210 'content-type': 'text/json', 211 }, 212 ) 213 214 expect(HTTPretty.last_request.method).to.equal('POST') 215 expect(HTTPretty.last_request.body).to.equal( 216 b'{"username": "gabrielfalcao"}', 217 ) 218 expect(HTTPretty.last_request.headers['content-type']).to.equal( 219 'text/json', 220 ) 221 expect(body).to.equal(b'{"repositories": ["HTTPretty", "lettuce"]}') 222 223 224@httprettified 225@within(two=miliseconds) 226def test_can_inspect_last_request_with_ssl(now): 227 "HTTPretty.last_request is recorded even when mocking 'https' (SSL)" 228 229 HTTPretty.register_uri(HTTPretty.POST, "https://secure.github.com/", 230 body='{"repositories": ["HTTPretty", "lettuce"]}') 231 232 headers, body = httplib2.Http().request( 233 'https://secure.github.com', 'POST', 234 body='{"username": "gabrielfalcao"}', 235 headers={ 236 'content-type': 'text/json', 237 }, 238 ) 239 240 expect(HTTPretty.last_request.method).to.equal('POST') 241 expect(HTTPretty.last_request.body).to.equal( 242 b'{"username": "gabrielfalcao"}', 243 ) 244 expect(HTTPretty.last_request.headers['content-type']).to.equal( 245 'text/json', 246 ) 247 expect(body).to.equal(b'{"repositories": ["HTTPretty", "lettuce"]}') 248 249 250@httprettified 251@within(two=miliseconds) 252def test_httpretty_ignores_querystrings_from_registered_uri(now): 253 "Registering URIs with query string cause them to be ignored" 254 255 HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/?id=123", 256 body="Find the best daily deals") 257 258 _, got = httplib2.Http().request('http://yipit.com/?id=123', 'GET') 259 260 expect(got).to.equal(b'Find the best daily deals') 261 expect(HTTPretty.last_request.method).to.equal('GET') 262 expect(HTTPretty.last_request.path).to.equal('/?id=123') 263 264 265@httprettified 266@within(two=miliseconds) 267def test_callback_response(now): 268 ("HTTPretty should call a callback function to be set as the body with" 269 " httplib2") 270 271 def request_callback(request, uri, headers): 272 return [200, headers, "The {} response from {}".format(decode_utf8(request.method), uri)] 273 274 HTTPretty.register_uri( 275 HTTPretty.GET, "https://api.yahoo.com/test", 276 body=request_callback) 277 278 headers1, body1 = httplib2.Http().request( 279 'https://api.yahoo.com/test', 'GET') 280 281 expect(body1).to.equal(b"The GET response from https://api.yahoo.com/test") 282 283 HTTPretty.register_uri( 284 HTTPretty.POST, "https://api.yahoo.com/test_post", 285 body=request_callback) 286 287 headers2, body2 = httplib2.Http().request( 288 'https://api.yahoo.com/test_post', 'POST') 289 290 expect(body2).to.equal(b"The POST response from https://api.yahoo.com/test_post") 291 292 293@httprettified 294def test_httpretty_should_allow_registering_regexes(): 295 "HTTPretty should allow registering regexes with httplib2" 296 297 HTTPretty.register_uri( 298 HTTPretty.GET, 299 'http://api.yipit.com/v1/deal;brand=gap', 300 body="Found brand", 301 ) 302 303 response, body = httplib2.Http().request('http://api.yipit.com/v1/deal;brand=gap', 'GET') 304 expect(body).to.equal(b'Found brand') 305 expect(HTTPretty.last_request.method).to.equal('GET') 306 expect(HTTPretty.last_request.path).to.equal('/v1/deal;brand=gap') 307