3 """Tests for yadis.discover.
5 @todo: Now that yadis.discover uses urljr.fetchers, we should be able to do
6 tests with a mock fetcher instead of spawning threads with BaseHTTPServer.
14 from openid
.yadis
.discover
import discover
, DiscoveryFailure
16 from openid
import fetchers
20 status_header_re
= re
.compile(r
'Status: (\d+) .*?$', re
.MULTILINE
)
23 Content-Type: text/plain
28 class QuitServer(Exception): pass
31 status_mo
= status_header_re
.match(data
)
32 headers_str
, body
= data
.split('\n\n', 1)
34 for line
in headers_str
.split('\n'):
35 k
, v
= line
.split(':', 1)
39 status
= int(status_mo
.group(1))
40 return fetchers
.HTTPResponse(status
=status
,
44 class TestFetcher(object):
45 def __init__(self
, base_url
):
46 self
.base_url
= base_url
48 def fetch(self
, url
, headers
, body
):
51 parsed
= urlparse
.urlparse(current_url
)
54 data
= discoverdata
.generateSample(path
, self
.base_url
)
56 return fetchers
.HTTPResponse(status
=404,
57 final_url
=current_url
,
61 response
= mkResponse(data
)
62 if response
.status
in [301, 302, 303, 307]:
63 current_url
= response
.headers
['location']
65 response
.final_url
= current_url
68 class TestSecondGet(unittest
.TestCase
):
69 class MockFetcher(object):
72 def fetch(self
, uri
, headers
=None, body
=None):
76 'X-XRDS-Location'.lower(): 'http://unittest/404',
78 return fetchers
.HTTPResponse(uri
, 200, headers
, '')
80 return fetchers
.HTTPResponse(uri
, 404)
83 self
.oldfetcher
= fetchers
.getDefaultFetcher()
84 fetchers
.setDefaultFetcher(self
.MockFetcher())
87 fetchers
.setDefaultFetcher(self
.oldfetcher
)
90 uri
= "http://something.unittest/"
91 self
.failUnlessRaises(DiscoveryFailure
, discover
, uri
)
94 class _TestCase(unittest
.TestCase
):
95 base_url
= 'http://invalid.unittest/'
97 def __init__(self
, input_name
, id_name
, result_name
, success
):
98 self
.input_name
= input_name
99 self
.id_name
= id_name
100 self
.result_name
= result_name
101 self
.success
= success
102 # Still not quite sure how to best construct these custom tests.
103 # Between python2.3 and python2.4, a patch attached to pyunit.sf.net
104 # bug #469444 got applied which breaks loadTestsFromModule on this
105 # class if it has test_ or runTest methods. So, kludge to change
107 unittest
.TestCase
.__init
__(self
, methodName
='runCustomTest')
110 fetchers
.setDefaultFetcher(TestFetcher(self
.base_url
),
111 wrap_exceptions
=False)
113 self
.input_url
, self
.expected
= discoverdata
.generateResult(
121 fetchers
.setDefaultFetcher(None)
123 def runCustomTest(self
):
124 if self
.expected
is DiscoveryFailure
:
125 self
.failUnlessRaises(DiscoveryFailure
,
126 discover
, self
.input_url
)
128 result
= discover(self
.input_url
)
129 self
.failUnlessEqual(self
.input_url
, result
.request_uri
)
131 msg
= 'Identity URL mismatch: actual = %r, expected = %r' % (
132 result
.normalized_uri
, self
.expected
.normalized_uri
)
133 self
.failUnlessEqual(
134 self
.expected
.normalized_uri
, result
.normalized_uri
, msg
)
136 msg
= 'Content mismatch: actual = %r, expected = %r' % (
137 result
.response_text
, self
.expected
.response_text
)
138 self
.failUnlessEqual(
139 self
.expected
.response_text
, result
.response_text
, msg
)
141 expected_keys
= dir(self
.expected
)
143 actual_keys
= dir(result
)
145 self
.failUnlessEqual(actual_keys
, expected_keys
)
147 for k
in dir(self
.expected
):
148 if k
.startswith('__') and k
.endswith('__'):
150 exp_v
= getattr(self
.expected
, k
)
151 if isinstance(exp_v
, types
.MethodType
):
153 act_v
= getattr(result
, k
)
154 assert act_v
== exp_v
, (k
, exp_v
, act_v
)
156 def shortDescription(self
):
159 except AttributeError:
160 # run before setUp, or if setUp did not complete successfully.
164 self
.__class
__.__module
__)
167 s
= unittest
.TestSuite()
168 for success
, input_name
, id_name
, result_name
in discoverdata
.testlist
:
169 test
= _TestCase(input_name
, id_name
, result_name
, success
)
175 runner
= unittest
.TextTestRunner()
176 return runner
.run(loadTests())
178 if __name__
== '__main__':