PageRenderTime 76ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/gems/ruby-openid-2.1.2/test/test_discover.rb

http://github.com/fudgestudios/bort
Ruby | 789 lines | 679 code | 88 blank | 22 comment | 8 complexity | 271f7932828cc6372469f7567176e3d8 MD5 | raw file
Possible License(s): MIT, Apache-2.0
  1. require 'testutil'
  2. require 'util'
  3. require 'test/unit'
  4. require 'openid/fetchers'
  5. require 'openid/yadis/discovery'
  6. require 'openid/consumer/discovery'
  7. require 'openid/yadis/xrires'
  8. require 'openid/yadis/xri'
  9. require 'openid/message'
  10. require 'openid/util'
  11. ### Tests for conditions that trigger DiscoveryFailure
  12. module OpenID
  13. class SimpleMockFetcher
  14. def initialize(test, responses)
  15. @test = test
  16. @responses = responses.dup
  17. end
  18. def fetch(url, body=nil, headers=nil, limit=nil)
  19. response = @responses.shift
  20. @test.assert(body.nil?)
  21. @test.assert_equal(response.final_url, url)
  22. return response
  23. end
  24. end
  25. class TestDiscoveryFailure < Test::Unit::TestCase
  26. def initialize(*args)
  27. super(*args)
  28. @responses = [
  29. [HTTPResponse._from_raw_data(nil, nil, {}, 'http://network.error/')],
  30. [HTTPResponse._from_raw_data(404, nil, {}, 'http://not.found/')],
  31. [HTTPResponse._from_raw_data(400, nil, {}, 'http://bad.request/')],
  32. [HTTPResponse._from_raw_data(500, nil, {}, 'http://server.error/')],
  33. [HTTPResponse._from_raw_data(200, nil, {'x-xrds-location' => 'http://xrds.missing/'},
  34. 'http://header.found/'),
  35. HTTPResponse._from_raw_data(404, nil, {}, 'http://xrds.missing/')],
  36. ]
  37. end
  38. def test_discovery_failure
  39. @responses.each { |response_set|
  40. @url = response_set[0].final_url
  41. OpenID.fetcher = SimpleMockFetcher.new(self, response_set)
  42. expected_status = response_set[-1].code
  43. begin
  44. OpenID.discover(@url)
  45. rescue DiscoveryFailure => why
  46. assert_equal(why.http_response.code, expected_status)
  47. else
  48. flunk('Did not raise DiscoveryFailure')
  49. end
  50. OpenID.fetcher = nil
  51. }
  52. end
  53. end
  54. ### Tests for raising/catching exceptions from the fetcher through
  55. ### the discover function
  56. class ErrorRaisingFetcher
  57. # Just raise an exception when fetch is called
  58. def initialize(thing_to_raise)
  59. @thing_to_raise = thing_to_raise
  60. end
  61. def fetch(url, body=nil, headers=nil, limit=nil)
  62. raise @thing_to_raise
  63. end
  64. end
  65. class DidFetch < Exception
  66. # Custom exception just to make sure it's not handled differently
  67. end
  68. class TestFetchException < Test::Unit::TestCase
  69. # Discovery should only raise DiscoveryFailure
  70. def initialize(*args)
  71. super(*args)
  72. @cases = [
  73. DidFetch.new(),
  74. Exception.new(),
  75. ArgumentError.new(),
  76. RuntimeError.new(),
  77. ]
  78. end
  79. def test_fetch_exception
  80. @cases.each { |exc|
  81. OpenID.fetcher = ErrorRaisingFetcher.new(exc)
  82. assert_raises(DiscoveryFailure) {
  83. OpenID.discover('http://doesnt.matter/')
  84. }
  85. OpenID.fetcher = nil
  86. }
  87. end
  88. end
  89. ### Tests for openid.consumer.discover.discover
  90. class TestNormalization < Test::Unit::TestCase
  91. def test_addingProtocol
  92. f = ErrorRaisingFetcher.new(RuntimeError.new())
  93. OpenID.fetcher = f
  94. begin
  95. OpenID.discover('users.stompy.janrain.com:8000/x')
  96. rescue DiscoveryFailure => why
  97. assert why.to_s.match("Failed to fetch")
  98. rescue RuntimeError
  99. end
  100. OpenID.fetcher = nil
  101. end
  102. end
  103. class DiscoveryMockFetcher
  104. def initialize(documents)
  105. @redirect = nil
  106. @documents = documents
  107. @fetchlog = []
  108. end
  109. def fetch(url, body=nil, headers=nil, limit=nil)
  110. @fetchlog << [url, body, headers]
  111. if @redirect
  112. final_url = @redirect
  113. else
  114. final_url = url
  115. end
  116. begin
  117. ctype, body = @documents.fetch(url)
  118. rescue IndexError
  119. status = 404
  120. ctype = 'text/plain'
  121. body = ''
  122. else
  123. status = 200
  124. end
  125. return HTTPResponse._from_raw_data(status, body, {'content-type' => ctype}, final_url)
  126. end
  127. end
  128. class BaseTestDiscovery < Test::Unit::TestCase
  129. attr_accessor :id_url, :fetcher_class
  130. def initialize(*args)
  131. super(*args)
  132. @id_url = "http://someuser.unittest/"
  133. @documents = {}
  134. @fetcher_class = DiscoveryMockFetcher
  135. end
  136. def _checkService(s, server_url, claimed_id=nil,
  137. local_id=nil, canonical_id=nil,
  138. types=nil, used_yadis=false,
  139. display_identifier=nil)
  140. assert_equal(server_url, s.server_url)
  141. if types == ['2.0 OP']
  142. assert(!claimed_id)
  143. assert(!local_id)
  144. assert(!s.claimed_id)
  145. assert(!s.local_id)
  146. assert(!s.get_local_id())
  147. assert(!s.compatibility_mode())
  148. assert(s.is_op_identifier())
  149. assert_equal(s.preferred_namespace(),
  150. OPENID_2_0_MESSAGE_NS)
  151. else
  152. assert_equal(claimed_id, s.claimed_id)
  153. assert_equal(local_id, s.get_local_id())
  154. end
  155. if used_yadis
  156. assert(s.used_yadis, "Expected to use Yadis")
  157. else
  158. assert(!s.used_yadis,
  159. "Expected to use old-style discovery")
  160. end
  161. openid_types = {
  162. '1.1' => OPENID_1_1_TYPE,
  163. '1.0' => OPENID_1_0_TYPE,
  164. '2.0' => OPENID_2_0_TYPE,
  165. '2.0 OP' => OPENID_IDP_2_0_TYPE,
  166. }
  167. type_uris = types.collect { |t| openid_types[t] }
  168. assert_equal(type_uris, s.type_uris)
  169. assert_equal(canonical_id, s.canonical_id)
  170. if canonical_id.nil?
  171. assert_equal(claimed_id, s.display_identifier)
  172. else
  173. assert_equal(display_identifier, s.display_identifier)
  174. end
  175. end
  176. def setup
  177. # @documents = @documents.dup
  178. @fetcher = @fetcher_class.new(@documents)
  179. OpenID.fetcher = @fetcher
  180. end
  181. def teardown
  182. OpenID.fetcher = nil
  183. end
  184. def test_blank
  185. # XXX to avoid > 0 test requirement
  186. end
  187. end
  188. # def readDataFile(filename):
  189. # module_directory = os.path.dirname(os.path.abspath(__file__))
  190. # filename = os.path.join(
  191. # module_directory, 'data', 'test_discover', filename)
  192. # return file(filename).read()
  193. class TestDiscovery < BaseTestDiscovery
  194. include TestDataMixin
  195. def _discover(content_type, data,
  196. expected_services, expected_id=nil)
  197. if expected_id.nil?
  198. expected_id = @id_url
  199. end
  200. @documents[@id_url] = [content_type, data]
  201. id_url, services = OpenID.discover(@id_url)
  202. assert_equal(expected_services, services.length)
  203. assert_equal(expected_id, id_url)
  204. return services
  205. end
  206. def test_404
  207. assert_raise(DiscoveryFailure) {
  208. OpenID.discover(@id_url + '/404')
  209. }
  210. end
  211. def test_noOpenID
  212. services = _discover('text/plain',
  213. "junk", 0)
  214. services = _discover(
  215. 'text/html',
  216. read_data_file('test_discover/openid_no_delegate.html', false),
  217. 1)
  218. _checkService(
  219. services[0],
  220. "http://www.myopenid.com/server",
  221. @id_url,
  222. @id_url,
  223. nil,
  224. ['1.1'],
  225. false)
  226. end
  227. def test_html1
  228. services = _discover('text/html',
  229. read_data_file('test_discover/openid.html', false),
  230. 1)
  231. _checkService(services[0],
  232. "http://www.myopenid.com/server",
  233. @id_url,
  234. 'http://smoker.myopenid.com/',
  235. nil,
  236. ['1.1'],
  237. false)
  238. end
  239. def test_html1Fragment
  240. # Ensure that the Claimed Identifier does not have a fragment if
  241. # one is supplied in the User Input.
  242. content_type = 'text/html'
  243. data = read_data_file('test_discover/openid.html', false)
  244. expected_services = 1
  245. @documents[@id_url] = [content_type, data]
  246. expected_id = @id_url
  247. @id_url = @id_url + '#fragment'
  248. id_url, services = OpenID.discover(@id_url)
  249. assert_equal(expected_services, services.length)
  250. assert_equal(expected_id, id_url)
  251. _checkService(services[0],
  252. "http://www.myopenid.com/server",
  253. expected_id,
  254. 'http://smoker.myopenid.com/',
  255. nil,
  256. ['1.1'],
  257. false)
  258. end
  259. def test_html2
  260. services = _discover('text/html',
  261. read_data_file('test_discover/openid2.html', false),
  262. 1)
  263. _checkService(services[0],
  264. "http://www.myopenid.com/server",
  265. @id_url,
  266. 'http://smoker.myopenid.com/',
  267. nil,
  268. ['2.0'],
  269. false)
  270. end
  271. def test_html1And2
  272. services = _discover(
  273. 'text/html',
  274. read_data_file('test_discover/openid_1_and_2.html', false),
  275. 2)
  276. services.zip(['2.0', '1.1']).each { |s, t|
  277. _checkService(s,
  278. "http://www.myopenid.com/server",
  279. @id_url,
  280. 'http://smoker.myopenid.com/',
  281. nil,
  282. [t],
  283. false)
  284. }
  285. end
  286. def test_yadisEmpty
  287. services = _discover('application/xrds+xml',
  288. read_data_file('test_discover/yadis_0entries.xml', false),
  289. 0)
  290. end
  291. def test_htmlEmptyYadis
  292. # HTML document has discovery information, but points to an
  293. # empty Yadis document. The XRDS document pointed to by
  294. # "openid_and_yadis.html"
  295. @documents[@id_url + 'xrds'] = ['application/xrds+xml',
  296. read_data_file('test_discover/yadis_0entries.xml', false)]
  297. services = _discover('text/html',
  298. read_data_file('test_discover/openid_and_yadis.html', false),
  299. 1)
  300. _checkService(services[0],
  301. "http://www.myopenid.com/server",
  302. @id_url,
  303. 'http://smoker.myopenid.com/',
  304. nil,
  305. ['1.1'],
  306. false)
  307. end
  308. def test_yadis1NoDelegate
  309. services = _discover('application/xrds+xml',
  310. read_data_file('test_discover/yadis_no_delegate.xml', false),
  311. 1)
  312. _checkService(services[0],
  313. "http://www.myopenid.com/server",
  314. @id_url,
  315. @id_url,
  316. nil,
  317. ['1.0'],
  318. true)
  319. end
  320. def test_yadis2NoLocalID
  321. services = _discover('application/xrds+xml',
  322. read_data_file('test_discover/openid2_xrds_no_local_id.xml', false),
  323. 1)
  324. _checkService(services[0],
  325. "http://www.myopenid.com/server",
  326. @id_url,
  327. @id_url,
  328. nil,
  329. ['2.0'],
  330. true)
  331. end
  332. def test_yadis2
  333. services = _discover('application/xrds+xml',
  334. read_data_file('test_discover/openid2_xrds.xml', false),
  335. 1)
  336. _checkService(services[0],
  337. "http://www.myopenid.com/server",
  338. @id_url,
  339. 'http://smoker.myopenid.com/',
  340. nil,
  341. ['2.0'],
  342. true)
  343. end
  344. def test_yadis2OP
  345. services = _discover('application/xrds+xml',
  346. read_data_file('test_discover/yadis_idp.xml', false),
  347. 1)
  348. _checkService(services[0],
  349. "http://www.myopenid.com/server",
  350. nil, nil, nil,
  351. ['2.0 OP'],
  352. true)
  353. end
  354. def test_yadis2OPDelegate
  355. # The delegate tag isn't meaningful for OP entries.
  356. services = _discover('application/xrds+xml',
  357. read_data_file('test_discover/yadis_idp_delegate.xml', false),
  358. 1)
  359. _checkService(services[0],
  360. "http://www.myopenid.com/server",
  361. nil, nil, nil,
  362. ['2.0 OP'],
  363. true)
  364. end
  365. def test_yadis2BadLocalID
  366. assert_raise(DiscoveryFailure) {
  367. _discover('application/xrds+xml',
  368. read_data_file('test_discover/yadis_2_bad_local_id.xml', false),
  369. 1)
  370. }
  371. end
  372. def test_yadis1And2
  373. services = _discover('application/xrds+xml',
  374. read_data_file('test_discover/openid_1_and_2_xrds.xml', false),
  375. 1)
  376. _checkService(services[0],
  377. "http://www.myopenid.com/server",
  378. @id_url,
  379. 'http://smoker.myopenid.com/',
  380. nil,
  381. ['2.0', '1.1'],
  382. true)
  383. end
  384. def test_yadis1And2BadLocalID
  385. assert_raise(DiscoveryFailure) {
  386. _discover('application/xrds+xml',
  387. read_data_file('test_discover/openid_1_and_2_xrds_bad_delegate.xml', false),
  388. 1)
  389. }
  390. end
  391. end
  392. class MockFetcherForXRIProxy
  393. def initialize(documents, proxy_url=Yadis::XRI::ProxyResolver::DEFAULT_PROXY)
  394. @documents = documents
  395. @fetchlog = []
  396. @proxy_url = nil
  397. end
  398. def fetch(url, body=nil, headers=nil, limit=nil)
  399. @fetchlog << [url, body, headers]
  400. u = URI::parse(url)
  401. proxy_host = u.host
  402. xri = u.path
  403. query = u.query
  404. if !headers and !query
  405. raise ArgumentError.new("No headers or query; you probably didn't " +
  406. "mean to do that.")
  407. end
  408. if xri.starts_with?('/')
  409. xri = xri[1..-1]
  410. end
  411. begin
  412. ctype, body = @documents.fetch(xri)
  413. rescue IndexError
  414. status = 404
  415. ctype = 'text/plain'
  416. body = ''
  417. else
  418. status = 200
  419. end
  420. return HTTPResponse._from_raw_data(status, body,
  421. {'content-type' => ctype}, url)
  422. end
  423. end
  424. class TestXRIDiscovery < BaseTestDiscovery
  425. include TestDataMixin
  426. include TestUtil
  427. def initialize(*args)
  428. super(*args)
  429. @fetcher_class = MockFetcherForXRIProxy
  430. @documents = {'=smoker' => ['application/xrds+xml',
  431. read_data_file('test_discover/yadis_2entries_delegate.xml', false)],
  432. '=smoker*bad' => ['application/xrds+xml',
  433. read_data_file('test_discover/yadis_another_delegate.xml', false)]}
  434. end
  435. def test_xri
  436. user_xri, services = OpenID.discover_xri('=smoker')
  437. _checkService(services[0],
  438. "http://www.myopenid.com/server",
  439. Yadis::XRI.make_xri("=!1000"),
  440. 'http://smoker.myopenid.com/',
  441. Yadis::XRI.make_xri("=!1000"),
  442. ['1.0'],
  443. true,
  444. '=smoker')
  445. _checkService(services[1],
  446. "http://www.livejournal.com/openid/server.bml",
  447. Yadis::XRI.make_xri("=!1000"),
  448. 'http://frank.livejournal.com/',
  449. Yadis::XRI.make_xri("=!1000"),
  450. ['1.0'],
  451. true,
  452. '=smoker')
  453. end
  454. def test_xriNoCanonicalID
  455. silence_logging {
  456. user_xri, services = OpenID.discover_xri('=smoker*bad')
  457. assert(services.empty?)
  458. }
  459. end
  460. def test_useCanonicalID
  461. # When there is no delegate, the CanonicalID should be used with
  462. # XRI.
  463. endpoint = OpenIDServiceEndpoint.new()
  464. endpoint.claimed_id = Yadis::XRI.make_xri("=!1000")
  465. endpoint.canonical_id = Yadis::XRI.make_xri("=!1000")
  466. assert_equal(endpoint.get_local_id, Yadis::XRI.make_xri("=!1000"))
  467. end
  468. end
  469. class TestXRIDiscoveryIDP < BaseTestDiscovery
  470. include TestDataMixin
  471. def initialize(*args)
  472. super(*args)
  473. @fetcher_class = MockFetcherForXRIProxy
  474. @documents = {'=smoker' => ['application/xrds+xml',
  475. read_data_file('test_discover/yadis_2entries_idp.xml', false)] }
  476. end
  477. def test_xri
  478. user_xri, services = OpenID.discover_xri('=smoker')
  479. assert(!services.empty?, "Expected services, got zero")
  480. assert_equal(services[0].server_url,
  481. "http://www.livejournal.com/openid/server.bml")
  482. end
  483. end
  484. class TestPreferredNamespace < Test::Unit::TestCase
  485. def initialize(*args)
  486. super(*args)
  487. @cases = [
  488. [OPENID1_NS, []],
  489. [OPENID1_NS, ['http://jyte.com/']],
  490. [OPENID1_NS, [OPENID_1_0_TYPE]],
  491. [OPENID1_NS, [OPENID_1_1_TYPE]],
  492. [OPENID2_NS, [OPENID_2_0_TYPE]],
  493. [OPENID2_NS, [OPENID_IDP_2_0_TYPE]],
  494. [OPENID2_NS, [OPENID_2_0_TYPE,
  495. OPENID_1_0_TYPE]],
  496. [OPENID2_NS, [OPENID_1_0_TYPE,
  497. OPENID_2_0_TYPE]],
  498. ]
  499. end
  500. def test_preferred_namespace
  501. @cases.each { |expected_ns, type_uris|
  502. endpoint = OpenIDServiceEndpoint.new()
  503. endpoint.type_uris = type_uris
  504. actual_ns = endpoint.preferred_namespace()
  505. assert_equal(actual_ns, expected_ns)
  506. }
  507. end
  508. end
  509. class TestIsOPIdentifier < Test::Unit::TestCase
  510. def setup
  511. @endpoint = OpenIDServiceEndpoint.new()
  512. end
  513. def test_none
  514. assert(!@endpoint.is_op_identifier())
  515. end
  516. def test_openid1_0
  517. @endpoint.type_uris = [OPENID_1_0_TYPE]
  518. assert(!@endpoint.is_op_identifier())
  519. end
  520. def test_openid1_1
  521. @endpoint.type_uris = [OPENID_1_1_TYPE]
  522. assert(!@endpoint.is_op_identifier())
  523. end
  524. def test_openid2
  525. @endpoint.type_uris = [OPENID_2_0_TYPE]
  526. assert(!@endpoint.is_op_identifier())
  527. end
  528. def test_openid2OP
  529. @endpoint.type_uris = [OPENID_IDP_2_0_TYPE]
  530. assert(@endpoint.is_op_identifier())
  531. end
  532. def test_multipleMissing
  533. @endpoint.type_uris = [OPENID_2_0_TYPE,
  534. OPENID_1_0_TYPE]
  535. assert(!@endpoint.is_op_identifier())
  536. end
  537. def test_multiplePresent
  538. @endpoint.type_uris = [OPENID_2_0_TYPE,
  539. OPENID_1_0_TYPE,
  540. OPENID_IDP_2_0_TYPE]
  541. assert(@endpoint.is_op_identifier())
  542. end
  543. end
  544. class TestFromOPEndpointURL < Test::Unit::TestCase
  545. def setup
  546. @op_endpoint_url = 'http://example.com/op/endpoint'
  547. @endpoint = OpenIDServiceEndpoint.from_op_endpoint_url(@op_endpoint_url)
  548. end
  549. def test_isOPEndpoint
  550. assert(@endpoint.is_op_identifier())
  551. end
  552. def test_noIdentifiers
  553. assert_equal(@endpoint.get_local_id, nil)
  554. assert_equal(@endpoint.claimed_id, nil)
  555. end
  556. def test_compatibility
  557. assert(!@endpoint.compatibility_mode())
  558. end
  559. def test_canonical_id
  560. assert_equal(@endpoint.canonical_id, nil)
  561. end
  562. def test_serverURL
  563. assert_equal(@endpoint.server_url, @op_endpoint_url)
  564. end
  565. end
  566. class TestDiscoverFunction < Test::Unit::TestCase
  567. def test_discover_function
  568. # XXX these were all different tests in python, but they're
  569. # combined here so I only have to use with_method_overridden
  570. # once.
  571. discoverXRI = Proc.new { |identifier|
  572. return 'XRI'
  573. }
  574. discoverURI = Proc.new { |identifier|
  575. return 'URI'
  576. }
  577. OpenID.extend(OverrideMethodMixin)
  578. OpenID.with_method_overridden(:discover_uri, discoverURI) do
  579. OpenID.with_method_overridden(:discover_xri, discoverXRI) do
  580. assert_equal('URI', OpenID.discover('http://woo!'))
  581. assert_equal('URI', OpenID.discover('not a URL or XRI'))
  582. assert_equal('XRI', OpenID.discover('xri://=something'))
  583. assert_equal('XRI', OpenID.discover('=something'))
  584. end
  585. end
  586. end
  587. end
  588. class TestEndpointSupportsType < Test::Unit::TestCase
  589. def setup
  590. @endpoint = OpenIDServiceEndpoint.new()
  591. end
  592. def failUnlessSupportsOnly(*types)
  593. ['foo',
  594. OPENID_1_1_TYPE,
  595. OPENID_1_0_TYPE,
  596. OPENID_2_0_TYPE,
  597. OPENID_IDP_2_0_TYPE].each { |t|
  598. if types.member?(t)
  599. assert(@endpoint.supports_type(t),
  600. sprintf("Must support %s", t))
  601. else
  602. assert(!@endpoint.supports_type(t),
  603. sprintf("Shouldn't support %s", t))
  604. end
  605. }
  606. end
  607. def test_supportsNothing
  608. failUnlessSupportsOnly()
  609. end
  610. def test_openid2
  611. @endpoint.type_uris = [OPENID_2_0_TYPE]
  612. failUnlessSupportsOnly(OPENID_2_0_TYPE)
  613. end
  614. def test_openid2provider
  615. @endpoint.type_uris = [OPENID_IDP_2_0_TYPE]
  616. failUnlessSupportsOnly(OPENID_IDP_2_0_TYPE,
  617. OPENID_2_0_TYPE)
  618. end
  619. def test_openid1_0
  620. @endpoint.type_uris = [OPENID_1_0_TYPE]
  621. failUnlessSupportsOnly(OPENID_1_0_TYPE)
  622. end
  623. def test_openid1_1
  624. @endpoint.type_uris = [OPENID_1_1_TYPE]
  625. failUnlessSupportsOnly(OPENID_1_1_TYPE)
  626. end
  627. def test_multiple
  628. @endpoint.type_uris = [OPENID_1_1_TYPE,
  629. OPENID_2_0_TYPE]
  630. failUnlessSupportsOnly(OPENID_1_1_TYPE,
  631. OPENID_2_0_TYPE)
  632. end
  633. def test_multipleWithProvider
  634. @endpoint.type_uris = [OPENID_1_1_TYPE,
  635. OPENID_2_0_TYPE,
  636. OPENID_IDP_2_0_TYPE]
  637. failUnlessSupportsOnly(OPENID_1_1_TYPE,
  638. OPENID_2_0_TYPE,
  639. OPENID_IDP_2_0_TYPE)
  640. end
  641. end
  642. class TestEndpointDisplayIdentifier < Test::Unit::TestCase
  643. def test_strip_fragment
  644. @endpoint = OpenIDServiceEndpoint.new()
  645. @endpoint.claimed_id = 'http://recycled.invalid/#123'
  646. assert_equal 'http://recycled.invalid/', @endpoint.display_identifier
  647. end
  648. end
  649. class TestNormalizeURL < Test::Unit::TestCase
  650. def test_no_host
  651. assert_raise(DiscoveryFailure) {
  652. OpenID::normalize_url('http:///too-many.invalid/slashes')
  653. }
  654. end
  655. end
  656. end