entp-ruby-openid 2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. data/CHANGELOG +215 -0
  2. data/INSTALL +47 -0
  3. data/LICENSE +210 -0
  4. data/NOTICE +2 -0
  5. data/README +85 -0
  6. data/UPGRADE +127 -0
  7. data/admin/runtests.rb +45 -0
  8. data/examples/README +32 -0
  9. data/examples/active_record_openid_store/README +58 -0
  10. data/examples/active_record_openid_store/XXX_add_open_id_store_to_db.rb +24 -0
  11. data/examples/active_record_openid_store/XXX_upgrade_open_id_store.rb +26 -0
  12. data/examples/active_record_openid_store/init.rb +8 -0
  13. data/examples/active_record_openid_store/lib/association.rb +10 -0
  14. data/examples/active_record_openid_store/lib/nonce.rb +3 -0
  15. data/examples/active_record_openid_store/lib/open_id_setting.rb +4 -0
  16. data/examples/active_record_openid_store/lib/openid_ar_store.rb +57 -0
  17. data/examples/active_record_openid_store/test/store_test.rb +212 -0
  18. data/examples/discover +49 -0
  19. data/examples/rails_openid/README +153 -0
  20. data/examples/rails_openid/Rakefile +10 -0
  21. data/examples/rails_openid/app/controllers/application.rb +4 -0
  22. data/examples/rails_openid/app/controllers/consumer_controller.rb +125 -0
  23. data/examples/rails_openid/app/controllers/login_controller.rb +45 -0
  24. data/examples/rails_openid/app/controllers/server_controller.rb +265 -0
  25. data/examples/rails_openid/app/helpers/application_helper.rb +3 -0
  26. data/examples/rails_openid/app/helpers/login_helper.rb +2 -0
  27. data/examples/rails_openid/app/helpers/server_helper.rb +9 -0
  28. data/examples/rails_openid/app/views/consumer/index.rhtml +81 -0
  29. data/examples/rails_openid/app/views/layouts/server.rhtml +68 -0
  30. data/examples/rails_openid/app/views/login/index.rhtml +56 -0
  31. data/examples/rails_openid/app/views/server/decide.rhtml +26 -0
  32. data/examples/rails_openid/config/boot.rb +19 -0
  33. data/examples/rails_openid/config/database.yml +74 -0
  34. data/examples/rails_openid/config/environment.rb +54 -0
  35. data/examples/rails_openid/config/environments/development.rb +19 -0
  36. data/examples/rails_openid/config/environments/production.rb +19 -0
  37. data/examples/rails_openid/config/environments/test.rb +19 -0
  38. data/examples/rails_openid/config/routes.rb +24 -0
  39. data/examples/rails_openid/doc/README_FOR_APP +2 -0
  40. data/examples/rails_openid/public/404.html +8 -0
  41. data/examples/rails_openid/public/500.html +8 -0
  42. data/examples/rails_openid/public/dispatch.cgi +12 -0
  43. data/examples/rails_openid/public/dispatch.fcgi +26 -0
  44. data/examples/rails_openid/public/dispatch.rb +12 -0
  45. data/examples/rails_openid/public/favicon.ico +0 -0
  46. data/examples/rails_openid/public/images/openid_login_bg.gif +0 -0
  47. data/examples/rails_openid/public/javascripts/controls.js +750 -0
  48. data/examples/rails_openid/public/javascripts/dragdrop.js +584 -0
  49. data/examples/rails_openid/public/javascripts/effects.js +854 -0
  50. data/examples/rails_openid/public/javascripts/prototype.js +1785 -0
  51. data/examples/rails_openid/public/robots.txt +1 -0
  52. data/examples/rails_openid/script/about +3 -0
  53. data/examples/rails_openid/script/breakpointer +3 -0
  54. data/examples/rails_openid/script/console +3 -0
  55. data/examples/rails_openid/script/destroy +3 -0
  56. data/examples/rails_openid/script/generate +3 -0
  57. data/examples/rails_openid/script/performance/benchmarker +3 -0
  58. data/examples/rails_openid/script/performance/profiler +3 -0
  59. data/examples/rails_openid/script/plugin +3 -0
  60. data/examples/rails_openid/script/process/reaper +3 -0
  61. data/examples/rails_openid/script/process/spawner +3 -0
  62. data/examples/rails_openid/script/process/spinner +3 -0
  63. data/examples/rails_openid/script/runner +3 -0
  64. data/examples/rails_openid/script/server +3 -0
  65. data/examples/rails_openid/test/functional/login_controller_test.rb +18 -0
  66. data/examples/rails_openid/test/functional/server_controller_test.rb +18 -0
  67. data/examples/rails_openid/test/test_helper.rb +28 -0
  68. data/lib/hmac/hmac.rb +112 -0
  69. data/lib/hmac/sha1.rb +11 -0
  70. data/lib/hmac/sha2.rb +25 -0
  71. data/lib/openid.rb +22 -0
  72. data/lib/openid/association.rb +249 -0
  73. data/lib/openid/consumer.rb +395 -0
  74. data/lib/openid/consumer/associationmanager.rb +344 -0
  75. data/lib/openid/consumer/checkid_request.rb +186 -0
  76. data/lib/openid/consumer/discovery.rb +497 -0
  77. data/lib/openid/consumer/discovery_manager.rb +123 -0
  78. data/lib/openid/consumer/html_parse.rb +134 -0
  79. data/lib/openid/consumer/idres.rb +523 -0
  80. data/lib/openid/consumer/responses.rb +150 -0
  81. data/lib/openid/cryptutil.rb +115 -0
  82. data/lib/openid/dh.rb +89 -0
  83. data/lib/openid/extension.rb +39 -0
  84. data/lib/openid/extensions/ax.rb +539 -0
  85. data/lib/openid/extensions/oauth.rb +91 -0
  86. data/lib/openid/extensions/pape.rb +179 -0
  87. data/lib/openid/extensions/sreg.rb +277 -0
  88. data/lib/openid/extras.rb +11 -0
  89. data/lib/openid/fetchers.rb +258 -0
  90. data/lib/openid/kvform.rb +136 -0
  91. data/lib/openid/kvpost.rb +58 -0
  92. data/lib/openid/message.rb +553 -0
  93. data/lib/openid/protocolerror.rb +12 -0
  94. data/lib/openid/server.rb +1544 -0
  95. data/lib/openid/store.rb +10 -0
  96. data/lib/openid/store/filesystem.rb +272 -0
  97. data/lib/openid/store/interface.rb +75 -0
  98. data/lib/openid/store/memcache.rb +109 -0
  99. data/lib/openid/store/memory.rb +84 -0
  100. data/lib/openid/store/nonce.rb +68 -0
  101. data/lib/openid/trustroot.rb +349 -0
  102. data/lib/openid/urinorm.rb +75 -0
  103. data/lib/openid/util.rb +119 -0
  104. data/lib/openid/version.rb +3 -0
  105. data/lib/openid/yadis.rb +15 -0
  106. data/lib/openid/yadis/accept.rb +148 -0
  107. data/lib/openid/yadis/constants.rb +21 -0
  108. data/lib/openid/yadis/discovery.rb +153 -0
  109. data/lib/openid/yadis/filters.rb +205 -0
  110. data/lib/openid/yadis/htmltokenizer.rb +305 -0
  111. data/lib/openid/yadis/parsehtml.rb +45 -0
  112. data/lib/openid/yadis/services.rb +42 -0
  113. data/lib/openid/yadis/xrds.rb +155 -0
  114. data/lib/openid/yadis/xri.rb +90 -0
  115. data/lib/openid/yadis/xrires.rb +91 -0
  116. data/test/data/test_discover/openid_utf8.html +11 -0
  117. data/test/support/test_data_mixin.rb +127 -0
  118. data/test/support/test_util.rb +53 -0
  119. data/test/support/yadis_data.rb +131 -0
  120. data/test/support/yadis_data/accept.txt +124 -0
  121. data/test/support/yadis_data/dh.txt +29 -0
  122. data/test/support/yadis_data/example-xrds.xml +14 -0
  123. data/test/support/yadis_data/linkparse.txt +587 -0
  124. data/test/support/yadis_data/n2b64 +650 -0
  125. data/test/support/yadis_data/test1-discover.txt +137 -0
  126. data/test/support/yadis_data/test1-parsehtml.txt +152 -0
  127. data/test/support/yadis_data/test_discover/malformed_meta_tag.html +19 -0
  128. data/test/support/yadis_data/test_discover/openid.html +11 -0
  129. data/test/support/yadis_data/test_discover/openid2.html +11 -0
  130. data/test/support/yadis_data/test_discover/openid2_xrds.xml +12 -0
  131. data/test/support/yadis_data/test_discover/openid2_xrds_no_local_id.xml +11 -0
  132. data/test/support/yadis_data/test_discover/openid_1_and_2.html +11 -0
  133. data/test/support/yadis_data/test_discover/openid_1_and_2_xrds.xml +16 -0
  134. data/test/support/yadis_data/test_discover/openid_1_and_2_xrds_bad_delegate.xml +17 -0
  135. data/test/support/yadis_data/test_discover/openid_and_yadis.html +12 -0
  136. data/test/support/yadis_data/test_discover/openid_no_delegate.html +10 -0
  137. data/test/support/yadis_data/test_discover/openid_utf8.html +11 -0
  138. data/test/support/yadis_data/test_discover/yadis_0entries.xml +12 -0
  139. data/test/support/yadis_data/test_discover/yadis_2_bad_local_id.xml +15 -0
  140. data/test/support/yadis_data/test_discover/yadis_2entries_delegate.xml +22 -0
  141. data/test/support/yadis_data/test_discover/yadis_2entries_idp.xml +21 -0
  142. data/test/support/yadis_data/test_discover/yadis_another_delegate.xml +14 -0
  143. data/test/support/yadis_data/test_discover/yadis_idp.xml +12 -0
  144. data/test/support/yadis_data/test_discover/yadis_idp_delegate.xml +13 -0
  145. data/test/support/yadis_data/test_discover/yadis_no_delegate.xml +11 -0
  146. data/test/support/yadis_data/test_xrds/=j3h.2007.11.14.xrds +25 -0
  147. data/test/support/yadis_data/test_xrds/README +12 -0
  148. data/test/support/yadis_data/test_xrds/delegated-20060809-r1.xrds +34 -0
  149. data/test/support/yadis_data/test_xrds/delegated-20060809-r2.xrds +34 -0
  150. data/test/support/yadis_data/test_xrds/delegated-20060809.xrds +34 -0
  151. data/test/support/yadis_data/test_xrds/no-xrd.xml +7 -0
  152. data/test/support/yadis_data/test_xrds/not-xrds.xml +2 -0
  153. data/test/support/yadis_data/test_xrds/prefixsometimes.xrds +34 -0
  154. data/test/support/yadis_data/test_xrds/ref.xrds +109 -0
  155. data/test/support/yadis_data/test_xrds/sometimesprefix.xrds +34 -0
  156. data/test/support/yadis_data/test_xrds/spoof1.xrds +25 -0
  157. data/test/support/yadis_data/test_xrds/spoof2.xrds +25 -0
  158. data/test/support/yadis_data/test_xrds/spoof3.xrds +37 -0
  159. data/test/support/yadis_data/test_xrds/status222.xrds +9 -0
  160. data/test/support/yadis_data/test_xrds/subsegments.xrds +58 -0
  161. data/test/support/yadis_data/test_xrds/valid-populated-xrds.xml +39 -0
  162. data/test/support/yadis_data/trustroot.txt +153 -0
  163. data/test/support/yadis_data/urinorm.txt +79 -0
  164. data/test/test_accept.rb +170 -0
  165. data/test/test_association.rb +268 -0
  166. data/test/test_associationmanager.rb +918 -0
  167. data/test/test_ax.rb +690 -0
  168. data/test/test_checkid_request.rb +293 -0
  169. data/test/test_consumer.rb +260 -0
  170. data/test/test_cryptutil.rb +119 -0
  171. data/test/test_dh.rb +85 -0
  172. data/test/test_discover.rb +848 -0
  173. data/test/test_discovery_manager.rb +259 -0
  174. data/test/test_extension.rb +46 -0
  175. data/test/test_extras.rb +35 -0
  176. data/test/test_fetchers.rb +554 -0
  177. data/test/test_filters.rb +269 -0
  178. data/test/test_helper.rb +4 -0
  179. data/test/test_idres.rb +961 -0
  180. data/test/test_kvform.rb +164 -0
  181. data/test/test_kvpost.rb +64 -0
  182. data/test/test_linkparse.rb +100 -0
  183. data/test/test_message.rb +1115 -0
  184. data/test/test_nonce.rb +89 -0
  185. data/test/test_oauth.rb +176 -0
  186. data/test/test_openid_yadis.rb +177 -0
  187. data/test/test_pape.rb +248 -0
  188. data/test/test_parsehtml.rb +79 -0
  189. data/test/test_responses.rb +63 -0
  190. data/test/test_server.rb +2455 -0
  191. data/test/test_sreg.rb +479 -0
  192. data/test/test_stores.rb +292 -0
  193. data/test/test_trustroot.rb +111 -0
  194. data/test/test_urinorm.rb +34 -0
  195. data/test/test_util.rb +145 -0
  196. data/test/test_xrds.rb +167 -0
  197. data/test/test_xri.rb +48 -0
  198. data/test/test_xrires.rb +67 -0
  199. data/test/test_yadis_discovery.rb +218 -0
  200. metadata +268 -0
@@ -0,0 +1,119 @@
1
+ # coding: ASCII-8BIT
2
+ require "test_helper"
3
+ require "openid/cryptutil"
4
+ require "pathname"
5
+
6
+ module OpenID
7
+ class CryptUtilTestCase < Test::Unit::TestCase
8
+ include TestDataMixin
9
+
10
+ BIG = 2 ** 256
11
+
12
+ def test_rand
13
+ # If this is not true, the rest of our test won't work
14
+ assert(BIG.is_a?(Bignum))
15
+
16
+ # It's possible that these will be small enough for fixnums, but
17
+ # extraorindarily unlikely.
18
+ a = OpenID::CryptUtil.rand(BIG)
19
+ b = OpenID::CryptUtil.rand(BIG)
20
+ assert(a.is_a?(Bignum))
21
+ assert(b.is_a?(Bignum))
22
+ assert_not_equal(a, b)
23
+ end
24
+
25
+ def test_rand_doesnt_depend_on_srand
26
+ Kernel.srand(1)
27
+ a = OpenID::CryptUtil.rand(BIG)
28
+ Kernel.srand(1)
29
+ b = OpenID::CryptUtil.rand(BIG)
30
+ assert_not_equal(a, b)
31
+ end
32
+
33
+ def test_random_binary_convert
34
+ (0..500).each do
35
+ n = (0..10).inject(0) {|sum, element| sum + OpenID::CryptUtil.rand(BIG) }
36
+ s = OpenID::CryptUtil.num_to_binary n
37
+ assert(s.is_a?(String))
38
+ n_converted_back = OpenID::CryptUtil.binary_to_num(s)
39
+ assert_equal(n, n_converted_back)
40
+ end
41
+ end
42
+
43
+ def test_enumerated_binary_convert
44
+ {
45
+ "\x00" => 0,
46
+ "\x01" => 1,
47
+ "\x7F" => 127,
48
+ "\x00\xFF" => 255,
49
+ "\x00\x80" => 128,
50
+ "\x00\x81" => 129,
51
+ "\x00\x80\x00" => 32768,
52
+ "OpenID is cool" => 1611215304203901150134421257416556,
53
+ }.each do |str, num|
54
+ num_prime = OpenID::CryptUtil.binary_to_num(str)
55
+ str_prime = OpenID::CryptUtil.num_to_binary(num)
56
+ assert_equal(num, num_prime)
57
+ assert_equal(str, str_prime)
58
+ end
59
+ end
60
+
61
+ def with_n2b64
62
+ read_data_file( 'n2b64').each do |line|
63
+ base64, base10 = line.chomp.split
64
+ yield base64, base10.to_i
65
+ end
66
+ end
67
+
68
+ def test_base64_to_num
69
+ with_n2b64 do |base64, num|
70
+ assert_equal(num, OpenID::CryptUtil.base64_to_num(base64))
71
+ end
72
+ end
73
+
74
+ def test_base64_to_num_invalid
75
+ assert_raises(ArgumentError) {
76
+ OpenID::CryptUtil.base64_to_num('!@#$')
77
+ }
78
+ end
79
+
80
+ def test_num_to_base64
81
+ with_n2b64 do |base64, num|
82
+ assert_equal(base64, OpenID::CryptUtil.num_to_base64(num))
83
+ end
84
+ end
85
+
86
+ def test_randomstring
87
+ s1 = OpenID::CryptUtil.random_string(42)
88
+ assert_equal(42, s1.length)
89
+ s2 = OpenID::CryptUtil.random_string(42)
90
+ assert_equal(42, s2.length)
91
+ assert_not_equal(s1, s2)
92
+ end
93
+
94
+ def test_randomstring_population
95
+ s1 = OpenID::CryptUtil.random_string(42, "XO")
96
+ assert_match(/[XO]{42}/, s1)
97
+ end
98
+
99
+ def test_sha1
100
+ assert_equal("\x11\xf6\xad\x8e\xc5*)\x84\xab\xaa\xfd|;Qe\x03x\\ r",
101
+ OpenID::CryptUtil.sha1('x'))
102
+ end
103
+
104
+ def test_hmac_sha1
105
+ assert_equal("\x8bo\xf7O\xa7\x18*\x90\xac ah\x16\xf7\xb8\x81JB\x9f|",
106
+ OpenID::CryptUtil.hmac_sha1('x', 'x'))
107
+ end
108
+
109
+ def test_sha256
110
+ assert_equal("-q\x16B\xb7&\xb0D\x01b|\xa9\xfb\xac2\xf5\xc8S\x0f\xb1\x90<\xc4\xdb\x02%\x87\x17\x92\x1aH\x81",
111
+ OpenID::CryptUtil.sha256('x'))
112
+ end
113
+
114
+ def test_hmac_sha256
115
+ assert_equal("\x94{\xd2w\xb2\xd3\\\xfc\x07\xfb\xc7\xe3b\xf2iuXz1\xf8:}\xffx\x8f\xda\xc1\xfaC\xc4\xb2\x87",
116
+ OpenID::CryptUtil.hmac_sha256('x', 'x'))
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,85 @@
1
+ require "test_helper"
2
+ require 'openid/dh'
3
+
4
+ module OpenID
5
+ class DiffieHellmanExposed < OpenID::DiffieHellman
6
+ def DiffieHellmanExposed.strxor_for_testing(a, b)
7
+ return DiffieHellmanExposed.strxor(a, b)
8
+ end
9
+ end
10
+
11
+ class DiffieHellmanTestCase < Test::Unit::TestCase
12
+ include OpenID::TestDataMixin
13
+
14
+ NUL = "\x00"
15
+
16
+ def test_strxor_success
17
+ [#input 1 input 2 expected
18
+ [NUL, NUL, NUL ],
19
+ ["\x01", NUL, "\x01" ],
20
+ ["a", "a", NUL ],
21
+ ["a", NUL, "a" ],
22
+ ["abc", NUL * 3, "abc" ],
23
+ ["x" * 10, NUL * 10, "x" * 10],
24
+ ["\x01", "\x02", "\x03" ],
25
+ ["\xf0", "\x0f", "\xff" ],
26
+ ["\xff", "\x0f", "\xf0" ],
27
+ ].each do |input1, input2, expected|
28
+ actual = DiffieHellmanExposed.strxor_for_testing(input1, input2)
29
+ assert_equal(expected, actual)
30
+ end
31
+ end
32
+
33
+ def test_strxor_failure
34
+ [
35
+ ['', 'a' ],
36
+ ['foo', 'ba' ],
37
+ [NUL * 3, NUL * 4],
38
+ [255, 127 ].map{|h| (0..h).map{|i|i.chr}.join('')},
39
+ ].each do |aa, bb|
40
+ assert_raises(ArgumentError) {
41
+ DiffieHellmanExposed.strxor(aa, bb)
42
+ }
43
+ end
44
+ end
45
+
46
+ def test_simple_exchange
47
+ dh1 = DiffieHellman.from_defaults()
48
+ dh2 = DiffieHellman.from_defaults()
49
+ secret1 = dh1.get_shared_secret(dh2.public)
50
+ secret2 = dh2.get_shared_secret(dh1.public)
51
+ assert_equal(secret1, secret2)
52
+ end
53
+
54
+ def test_xor_secret
55
+ dh1 = DiffieHellman.from_defaults()
56
+ dh2 = DiffieHellman.from_defaults()
57
+ secret = "Shhhhhh! don't tell!"
58
+ encrypted = dh1.xor_secret((CryptUtil.method :sha1), dh2.public, secret)
59
+ decrypted = dh2.xor_secret((CryptUtil.method :sha1), dh1.public, encrypted)
60
+ assert_equal(secret, decrypted)
61
+ end
62
+
63
+ def test_dh
64
+ dh = DiffieHellman.from_defaults()
65
+ class << dh
66
+ def set_private_test(priv)
67
+ set_private(priv)
68
+ end
69
+ end
70
+
71
+ read_data_file('dh.txt', true).each do |line|
72
+ priv, pub = line.split(' ').map {|x| x.to_i}
73
+ dh.set_private_test(priv)
74
+ assert_equal(dh.public, pub)
75
+ end
76
+ end
77
+
78
+ def test_using_defaults
79
+ dh = DiffieHellman.from_defaults()
80
+ assert(dh.using_default_values?)
81
+ dh = DiffieHellman.new(3, 2750161)
82
+ assert(!dh.using_default_values?)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,848 @@
1
+ require 'test_helper'
2
+ require 'openid/fetchers'
3
+ require 'openid/yadis/discovery'
4
+ require 'openid/consumer/discovery'
5
+ require 'openid/yadis/xrires'
6
+ require 'openid/yadis/xri'
7
+ require 'openid/message'
8
+ require 'openid/util'
9
+
10
+ ### Tests for conditions that trigger DiscoveryFailure
11
+
12
+ module OpenID
13
+ class SimpleMockFetcher
14
+ def initialize(test, responses)
15
+ @test = test
16
+ @responses = responses.dup
17
+ end
18
+
19
+ def fetch(url, body=nil, headers=nil, limit=nil)
20
+ response = @responses.shift
21
+ @test.assert(body.nil?)
22
+ @test.assert_equal(response.final_url, url)
23
+ return response
24
+ end
25
+ end
26
+
27
+ class TestDiscoveryFailure < Test::Unit::TestCase
28
+ def initialize(*args)
29
+ super(*args)
30
+
31
+ @responses = [
32
+ [HTTPResponse._from_raw_data(nil, nil, {}, 'http://network.error/')],
33
+ [HTTPResponse._from_raw_data(404, nil, {}, 'http://not.found/')],
34
+ [HTTPResponse._from_raw_data(400, nil, {}, 'http://bad.request/')],
35
+ [HTTPResponse._from_raw_data(500, nil, {}, 'http://server.error/')],
36
+ [HTTPResponse._from_raw_data(200, nil, {'x-xrds-location' => 'http://xrds.missing/'},
37
+ 'http://header.found/'),
38
+ HTTPResponse._from_raw_data(404, nil, {}, 'http://xrds.missing/')],
39
+ ]
40
+ end
41
+
42
+ def test_discovery_failure
43
+
44
+ @responses.each { |response_set|
45
+ @url = response_set[0].final_url
46
+ OpenID.fetcher = SimpleMockFetcher.new(self, response_set)
47
+
48
+ expected_status = response_set[-1].code
49
+ begin
50
+ OpenID.discover(@url)
51
+ rescue DiscoveryFailure => why
52
+ assert_equal(why.http_response.code, expected_status)
53
+ else
54
+ flunk('Did not raise DiscoveryFailure')
55
+ end
56
+
57
+ OpenID.fetcher = nil
58
+ }
59
+ end
60
+ end
61
+
62
+ ### Tests for raising/catching exceptions from the fetcher through
63
+ ### the discover function
64
+
65
+ class ErrorRaisingFetcher
66
+ # Just raise an exception when fetch is called
67
+
68
+ def initialize(thing_to_raise)
69
+ @thing_to_raise = thing_to_raise
70
+ end
71
+
72
+ def fetch(url, body=nil, headers=nil, limit=nil)
73
+ raise @thing_to_raise
74
+ end
75
+ end
76
+
77
+ class DidFetch < Exception
78
+ # Custom exception just to make sure it's not handled differently
79
+ end
80
+
81
+ class TestFetchException < Test::Unit::TestCase
82
+ # Discovery should only raise DiscoveryFailure
83
+
84
+ def initialize(*args)
85
+ super(*args)
86
+
87
+ @cases = [
88
+ DidFetch.new(),
89
+ Exception.new(),
90
+ ArgumentError.new(),
91
+ RuntimeError.new(),
92
+ ]
93
+ end
94
+
95
+ def test_fetch_exception
96
+ @cases.each { |exc|
97
+ OpenID.fetcher = ErrorRaisingFetcher.new(exc)
98
+ assert_raises(DiscoveryFailure) {
99
+ OpenID.discover('http://doesnt.matter/')
100
+ }
101
+ OpenID.fetcher = nil
102
+ }
103
+ end
104
+ end
105
+
106
+ ### Tests for openid.consumer.discover.discover
107
+
108
+ class TestNormalization < Test::Unit::TestCase
109
+ def test_addingProtocol
110
+ f = ErrorRaisingFetcher.new(RuntimeError.new())
111
+ OpenID.fetcher = f
112
+
113
+ begin
114
+ OpenID.discover('users.stompy.janrain.com:8000/x')
115
+ rescue DiscoveryFailure => why
116
+ assert why.to_s.match("Failed to fetch")
117
+ rescue RuntimeError
118
+ end
119
+
120
+ OpenID.fetcher = nil
121
+ end
122
+ end
123
+
124
+ class DiscoveryMockFetcher
125
+ def initialize(documents)
126
+ @redirect = nil
127
+ @documents = documents
128
+ @fetchlog = []
129
+ end
130
+
131
+ def fetch(url, body=nil, headers=nil, limit=nil)
132
+ @fetchlog << [url, body, headers]
133
+ if @redirect
134
+ final_url = @redirect
135
+ else
136
+ final_url = url
137
+ end
138
+
139
+ begin
140
+ ctype, body = @documents.fetch(url)
141
+ rescue IndexError
142
+ status = 404
143
+ ctype = 'text/plain'
144
+ body = ''
145
+ else
146
+ status = 200
147
+ end
148
+
149
+ return HTTPResponse._from_raw_data(status, body, {'content-type' => ctype}, final_url)
150
+ end
151
+ end
152
+
153
+ class BaseTestDiscovery < Test::Unit::TestCase
154
+ attr_accessor :id_url, :fetcher_class
155
+
156
+ def initialize(*args)
157
+ super(*args)
158
+ @id_url = "http://someuser.unittest/"
159
+ @documents = {}
160
+ @fetcher_class = DiscoveryMockFetcher
161
+ end
162
+
163
+ def _checkService(s, server_url, claimed_id=nil,
164
+ local_id=nil, canonical_id=nil,
165
+ types=nil, used_yadis=false,
166
+ display_identifier=nil)
167
+ assert_equal(server_url, s.server_url)
168
+ if types == ['2.0 OP']
169
+ assert(!claimed_id)
170
+ assert(!local_id)
171
+ assert(!s.claimed_id)
172
+ assert(!s.local_id)
173
+ assert(!s.get_local_id())
174
+ assert(!s.compatibility_mode())
175
+ assert(s.is_op_identifier())
176
+ assert_equal(s.preferred_namespace(),
177
+ OPENID_2_0_MESSAGE_NS)
178
+ else
179
+ assert_equal(claimed_id, s.claimed_id)
180
+ assert_equal(local_id, s.get_local_id())
181
+ end
182
+
183
+ if used_yadis
184
+ assert(s.used_yadis, "Expected to use Yadis")
185
+ else
186
+ assert(!s.used_yadis,
187
+ "Expected to use old-style discovery")
188
+ end
189
+
190
+ openid_types = {
191
+ '1.1' => OPENID_1_1_TYPE,
192
+ '1.0' => OPENID_1_0_TYPE,
193
+ '2.0' => OPENID_2_0_TYPE,
194
+ '2.0 OP' => OPENID_IDP_2_0_TYPE,
195
+ }
196
+
197
+ type_uris = types.collect { |t| openid_types[t] }
198
+
199
+ assert_equal(type_uris, s.type_uris)
200
+ assert_equal(canonical_id, s.canonical_id)
201
+
202
+ if canonical_id.nil?
203
+ assert_equal(claimed_id, s.display_identifier)
204
+ else
205
+ assert_equal(display_identifier, s.display_identifier)
206
+ end
207
+ end
208
+
209
+ def setup
210
+ # @documents = @documents.dup
211
+ @fetcher = @fetcher_class.new(@documents)
212
+ OpenID.fetcher = @fetcher
213
+ end
214
+
215
+ def teardown
216
+ OpenID.fetcher = nil
217
+ end
218
+
219
+ def test_blank
220
+ # XXX to avoid > 0 test requirement
221
+ end
222
+ end
223
+
224
+ # def readDataFile(filename):
225
+ # module_directory = os.path.dirname(os.path.abspath(__file__))
226
+ # filename = os.path.join(
227
+ # module_directory, 'yadis_data', 'test_discover', filename)
228
+ # return file(filename).read()
229
+
230
+ class TestDiscovery < BaseTestDiscovery
231
+ include TestDataMixin
232
+
233
+ def _discover(content_type, data,
234
+ expected_services, expected_id=nil)
235
+ if expected_id.nil?
236
+ expected_id = @id_url
237
+ end
238
+
239
+ @documents[@id_url] = [content_type, data]
240
+ id_url, services = OpenID.discover(@id_url)
241
+
242
+ assert_equal(expected_services, services.length)
243
+ assert_equal(expected_id, id_url)
244
+ return services
245
+ end
246
+
247
+ def test_404
248
+ assert_raise(DiscoveryFailure) {
249
+ OpenID.discover(@id_url + '/404')
250
+ }
251
+ end
252
+
253
+ def test_noOpenID
254
+ services = _discover('text/plain',
255
+ "junk", 0)
256
+
257
+ services = _discover(
258
+ 'text/html',
259
+ read_data_file('test_discover/openid_no_delegate.html', false),
260
+ 1)
261
+
262
+ _checkService(
263
+ services[0],
264
+ "http://www.myopenid.com/server",
265
+ @id_url,
266
+ @id_url,
267
+ nil,
268
+ ['1.1'],
269
+ false)
270
+ end
271
+
272
+ def test_malformed_meta_tag
273
+ @id_url = "http://user.myopenid.com/"
274
+
275
+ services = _discover(
276
+ 'text/html',
277
+ read_data_file('test_discover/malformed_meta_tag.html', false),
278
+ 2)
279
+
280
+ _checkService(
281
+ services[0],
282
+ "http://www.myopenid.com/server",
283
+ @id_url,
284
+ @id_url,
285
+ nil,
286
+ ['2.0'],
287
+ false)
288
+
289
+ _checkService(
290
+ services[1],
291
+ "http://www.myopenid.com/server",
292
+ @id_url,
293
+ @id_url,
294
+ nil,
295
+ ['1.1'],
296
+ false)
297
+ end
298
+
299
+ def test_html1
300
+ services = _discover('text/html',
301
+ read_data_file('test_discover/openid.html', false),
302
+ 1)
303
+
304
+ _checkService(services[0],
305
+ "http://www.myopenid.com/server",
306
+ @id_url,
307
+ 'http://smoker.myopenid.com/',
308
+ nil,
309
+ ['1.1'],
310
+ false)
311
+ end
312
+
313
+ def test_html1Fragment
314
+ # Ensure that the Claimed Identifier does not have a fragment if
315
+ # one is supplied in the User Input.
316
+ content_type = 'text/html'
317
+ data = read_data_file('test_discover/openid.html', false)
318
+ expected_services = 1
319
+
320
+ @documents[@id_url] = [content_type, data]
321
+ expected_id = @id_url
322
+ @id_url = @id_url + '#fragment'
323
+ id_url, services = OpenID.discover(@id_url)
324
+
325
+ assert_equal(expected_services, services.length)
326
+ assert_equal(expected_id, id_url)
327
+
328
+ _checkService(services[0],
329
+ "http://www.myopenid.com/server",
330
+ expected_id,
331
+ 'http://smoker.myopenid.com/',
332
+ nil,
333
+ ['1.1'],
334
+ false)
335
+ end
336
+
337
+ def test_html2
338
+ services = _discover('text/html',
339
+ read_data_file('test_discover/openid2.html', false),
340
+ 1)
341
+
342
+ _checkService(services[0],
343
+ "http://www.myopenid.com/server",
344
+ @id_url,
345
+ 'http://smoker.myopenid.com/',
346
+ nil,
347
+ ['2.0'],
348
+ false)
349
+ end
350
+
351
+ def test_html1And2
352
+ services = _discover(
353
+ 'text/html',
354
+ read_data_file('test_discover/openid_1_and_2.html', false),
355
+ 2)
356
+
357
+ services.zip(['2.0', '1.1']).each { |s, t|
358
+ _checkService(s,
359
+ "http://www.myopenid.com/server",
360
+ @id_url,
361
+ 'http://smoker.myopenid.com/',
362
+ nil,
363
+ [t],
364
+ false)
365
+ }
366
+ end
367
+
368
+ def test_html_utf8
369
+ utf8_html = read_data_file('test_discover/openid_utf8.html', false)
370
+ utf8_html.force_encoding("UTF-8") if utf8_html.respond_to?(:force_encoding)
371
+ services = _discover('text/html', utf8_html, 1)
372
+
373
+ _checkService(services[0],
374
+ "http://www.myopenid.com/server",
375
+ @id_url,
376
+ 'http://smoker.myopenid.com/',
377
+ nil,
378
+ ['1.1'],
379
+ false)
380
+ end
381
+
382
+ def test_yadisEmpty
383
+ services = _discover('application/xrds+xml',
384
+ read_data_file('test_discover/yadis_0entries.xml', false),
385
+ 0)
386
+ end
387
+
388
+ def test_htmlEmptyYadis
389
+ # HTML document has discovery information, but points to an
390
+ # empty Yadis document. The XRDS document pointed to by
391
+ # "openid_and_yadis.html"
392
+ @documents[@id_url + 'xrds'] = ['application/xrds+xml',
393
+ read_data_file('test_discover/yadis_0entries.xml', false)]
394
+
395
+ services = _discover('text/html',
396
+ read_data_file('test_discover/openid_and_yadis.html', false),
397
+ 1)
398
+
399
+ _checkService(services[0],
400
+ "http://www.myopenid.com/server",
401
+ @id_url,
402
+ 'http://smoker.myopenid.com/',
403
+ nil,
404
+ ['1.1'],
405
+ false)
406
+ end
407
+
408
+ def test_yadis1NoDelegate
409
+ services = _discover('application/xrds+xml',
410
+ read_data_file('test_discover/yadis_no_delegate.xml', false),
411
+ 1)
412
+
413
+ _checkService(services[0],
414
+ "http://www.myopenid.com/server",
415
+ @id_url,
416
+ @id_url,
417
+ nil,
418
+ ['1.0'],
419
+ true)
420
+ end
421
+
422
+ def test_yadis2NoLocalID
423
+ services = _discover('application/xrds+xml',
424
+ read_data_file('test_discover/openid2_xrds_no_local_id.xml', false),
425
+ 1)
426
+
427
+ _checkService(services[0],
428
+ "http://www.myopenid.com/server",
429
+ @id_url,
430
+ @id_url,
431
+ nil,
432
+ ['2.0'],
433
+ true)
434
+ end
435
+
436
+ def test_yadis2
437
+ services = _discover('application/xrds+xml',
438
+ read_data_file('test_discover/openid2_xrds.xml', false),
439
+ 1)
440
+
441
+ _checkService(services[0],
442
+ "http://www.myopenid.com/server",
443
+ @id_url,
444
+ 'http://smoker.myopenid.com/',
445
+ nil,
446
+ ['2.0'],
447
+ true)
448
+ end
449
+
450
+ def test_yadis2OP
451
+ services = _discover('application/xrds+xml',
452
+ read_data_file('test_discover/yadis_idp.xml', false),
453
+ 1)
454
+
455
+ _checkService(services[0],
456
+ "http://www.myopenid.com/server",
457
+ nil, nil, nil,
458
+ ['2.0 OP'],
459
+ true)
460
+ end
461
+
462
+ def test_yadis2OPDelegate
463
+ # The delegate tag isn't meaningful for OP entries.
464
+ services = _discover('application/xrds+xml',
465
+ read_data_file('test_discover/yadis_idp_delegate.xml', false),
466
+ 1)
467
+
468
+ _checkService(services[0],
469
+ "http://www.myopenid.com/server",
470
+ nil, nil, nil,
471
+ ['2.0 OP'],
472
+ true)
473
+ end
474
+
475
+ def test_yadis2BadLocalID
476
+ assert_raise(DiscoveryFailure) {
477
+ _discover('application/xrds+xml',
478
+ read_data_file('test_discover/yadis_2_bad_local_id.xml', false),
479
+ 1)
480
+ }
481
+ end
482
+
483
+ def test_yadis1And2
484
+ services = _discover('application/xrds+xml',
485
+ read_data_file('test_discover/openid_1_and_2_xrds.xml', false),
486
+ 1)
487
+
488
+ _checkService(services[0],
489
+ "http://www.myopenid.com/server",
490
+ @id_url,
491
+ 'http://smoker.myopenid.com/',
492
+ nil,
493
+ ['2.0', '1.1'],
494
+ true)
495
+ end
496
+
497
+ def test_yadis1And2BadLocalID
498
+ assert_raise(DiscoveryFailure) {
499
+ _discover('application/xrds+xml',
500
+ read_data_file('test_discover/openid_1_and_2_xrds_bad_delegate.xml', false),
501
+ 1)
502
+ }
503
+ end
504
+ end
505
+
506
+ class MockFetcherForXRIProxy
507
+
508
+ def initialize(documents, proxy_url=Yadis::XRI::ProxyResolver::DEFAULT_PROXY)
509
+ @documents = documents
510
+ @fetchlog = []
511
+ @proxy_url = nil
512
+ end
513
+
514
+ def fetch(url, body=nil, headers=nil, limit=nil)
515
+ @fetchlog << [url, body, headers]
516
+
517
+ u = URI::parse(url)
518
+ proxy_host = u.host
519
+ xri = u.path
520
+ query = u.query
521
+
522
+ if !headers and !query
523
+ raise ArgumentError.new("No headers or query; you probably didn't " +
524
+ "mean to do that.")
525
+ end
526
+
527
+ if xri.starts_with?('/')
528
+ xri = xri[1..-1]
529
+ end
530
+
531
+ begin
532
+ ctype, body = @documents.fetch(xri)
533
+ rescue IndexError
534
+ status = 404
535
+ ctype = 'text/plain'
536
+ body = ''
537
+ else
538
+ status = 200
539
+ end
540
+
541
+ return HTTPResponse._from_raw_data(status, body,
542
+ {'content-type' => ctype}, url)
543
+ end
544
+ end
545
+
546
+ class TestXRIDiscovery < BaseTestDiscovery
547
+
548
+ include TestDataMixin
549
+ include TestUtil
550
+
551
+ def initialize(*args)
552
+ super(*args)
553
+
554
+ @fetcher_class = MockFetcherForXRIProxy
555
+
556
+ @documents = {'=smoker' => ['application/xrds+xml',
557
+ read_data_file('test_discover/yadis_2entries_delegate.xml', false)],
558
+ '=smoker*bad' => ['application/xrds+xml',
559
+ read_data_file('test_discover/yadis_another_delegate.xml', false)]}
560
+ end
561
+
562
+ def test_xri
563
+ user_xri, services = OpenID.discover_xri('=smoker')
564
+
565
+ _checkService(services[0],
566
+ "http://www.myopenid.com/server",
567
+ Yadis::XRI.make_xri("=!1000"),
568
+ 'http://smoker.myopenid.com/',
569
+ Yadis::XRI.make_xri("=!1000"),
570
+ ['1.0'],
571
+ true,
572
+ '=smoker')
573
+
574
+ _checkService(services[1],
575
+ "http://www.livejournal.com/openid/server.bml",
576
+ Yadis::XRI.make_xri("=!1000"),
577
+ 'http://frank.livejournal.com/',
578
+ Yadis::XRI.make_xri("=!1000"),
579
+ ['1.0'],
580
+ true,
581
+ '=smoker')
582
+ end
583
+
584
+ def test_xri_normalize
585
+ user_xri, services = OpenID.discover_xri('xri://=smoker')
586
+
587
+ _checkService(services[0],
588
+ "http://www.myopenid.com/server",
589
+ Yadis::XRI.make_xri("=!1000"),
590
+ 'http://smoker.myopenid.com/',
591
+ Yadis::XRI.make_xri("=!1000"),
592
+ ['1.0'],
593
+ true,
594
+ '=smoker')
595
+
596
+ _checkService(services[1],
597
+ "http://www.livejournal.com/openid/server.bml",
598
+ Yadis::XRI.make_xri("=!1000"),
599
+ 'http://frank.livejournal.com/',
600
+ Yadis::XRI.make_xri("=!1000"),
601
+ ['1.0'],
602
+ true,
603
+ '=smoker')
604
+ end
605
+
606
+ def test_xriNoCanonicalID
607
+ silence_logging {
608
+ user_xri, services = OpenID.discover_xri('=smoker*bad')
609
+ assert(services.empty?)
610
+ }
611
+ end
612
+
613
+ def test_useCanonicalID
614
+ # When there is no delegate, the CanonicalID should be used with
615
+ # XRI.
616
+ endpoint = OpenIDServiceEndpoint.new()
617
+ endpoint.claimed_id = Yadis::XRI.make_xri("=!1000")
618
+ endpoint.canonical_id = Yadis::XRI.make_xri("=!1000")
619
+ assert_equal(endpoint.get_local_id, Yadis::XRI.make_xri("=!1000"))
620
+ end
621
+ end
622
+
623
+ class TestXRIDiscoveryIDP < BaseTestDiscovery
624
+ include TestDataMixin
625
+
626
+ def initialize(*args)
627
+ super(*args)
628
+
629
+ @fetcher_class = MockFetcherForXRIProxy
630
+
631
+ @documents = {'=smoker' => ['application/xrds+xml',
632
+ read_data_file('test_discover/yadis_2entries_idp.xml', false)] }
633
+ end
634
+
635
+ def test_xri
636
+ user_xri, services = OpenID.discover_xri('=smoker')
637
+ assert(!services.empty?, "Expected services, got zero")
638
+ assert_equal(services[0].server_url,
639
+ "http://www.livejournal.com/openid/server.bml")
640
+ end
641
+ end
642
+
643
+ class TestPreferredNamespace < Test::Unit::TestCase
644
+ def initialize(*args)
645
+ super(*args)
646
+
647
+ @cases = [
648
+ [OPENID1_NS, []],
649
+ [OPENID1_NS, ['http://jyte.com/']],
650
+ [OPENID1_NS, [OPENID_1_0_TYPE]],
651
+ [OPENID1_NS, [OPENID_1_1_TYPE]],
652
+ [OPENID2_NS, [OPENID_2_0_TYPE]],
653
+ [OPENID2_NS, [OPENID_IDP_2_0_TYPE]],
654
+ [OPENID2_NS, [OPENID_2_0_TYPE,
655
+ OPENID_1_0_TYPE]],
656
+ [OPENID2_NS, [OPENID_1_0_TYPE,
657
+ OPENID_2_0_TYPE]],
658
+ ]
659
+ end
660
+
661
+ def test_preferred_namespace
662
+
663
+ @cases.each { |expected_ns, type_uris|
664
+ endpoint = OpenIDServiceEndpoint.new()
665
+ endpoint.type_uris = type_uris
666
+ actual_ns = endpoint.preferred_namespace()
667
+ assert_equal(actual_ns, expected_ns)
668
+ }
669
+ end
670
+ end
671
+
672
+ class TestIsOPIdentifier < Test::Unit::TestCase
673
+ def setup
674
+ @endpoint = OpenIDServiceEndpoint.new()
675
+ end
676
+
677
+ def test_none
678
+ assert(!@endpoint.is_op_identifier())
679
+ end
680
+
681
+ def test_openid1_0
682
+ @endpoint.type_uris = [OPENID_1_0_TYPE]
683
+ assert(!@endpoint.is_op_identifier())
684
+ end
685
+
686
+ def test_openid1_1
687
+ @endpoint.type_uris = [OPENID_1_1_TYPE]
688
+ assert(!@endpoint.is_op_identifier())
689
+ end
690
+
691
+ def test_openid2
692
+ @endpoint.type_uris = [OPENID_2_0_TYPE]
693
+ assert(!@endpoint.is_op_identifier())
694
+ end
695
+
696
+ def test_openid2OP
697
+ @endpoint.type_uris = [OPENID_IDP_2_0_TYPE]
698
+ assert(@endpoint.is_op_identifier())
699
+ end
700
+
701
+ def test_multipleMissing
702
+ @endpoint.type_uris = [OPENID_2_0_TYPE,
703
+ OPENID_1_0_TYPE]
704
+ assert(!@endpoint.is_op_identifier())
705
+ end
706
+
707
+ def test_multiplePresent
708
+ @endpoint.type_uris = [OPENID_2_0_TYPE,
709
+ OPENID_1_0_TYPE,
710
+ OPENID_IDP_2_0_TYPE]
711
+ assert(@endpoint.is_op_identifier())
712
+ end
713
+ end
714
+
715
+ class TestFromOPEndpointURL < Test::Unit::TestCase
716
+ def setup
717
+ @op_endpoint_url = 'http://example.com/op/endpoint'
718
+ @endpoint = OpenIDServiceEndpoint.from_op_endpoint_url(@op_endpoint_url)
719
+ end
720
+
721
+ def test_isOPEndpoint
722
+ assert(@endpoint.is_op_identifier())
723
+ end
724
+
725
+ def test_noIdentifiers
726
+ assert_equal(@endpoint.get_local_id, nil)
727
+ assert_equal(@endpoint.claimed_id, nil)
728
+ end
729
+
730
+ def test_compatibility
731
+ assert(!@endpoint.compatibility_mode())
732
+ end
733
+
734
+ def test_canonical_id
735
+ assert_equal(@endpoint.canonical_id, nil)
736
+ end
737
+
738
+ def test_serverURL
739
+ assert_equal(@endpoint.server_url, @op_endpoint_url)
740
+ end
741
+ end
742
+
743
+ class TestDiscoverFunction < Test::Unit::TestCase
744
+ def test_discover_function
745
+ # XXX these were all different tests in python, but they're
746
+ # combined here so I only have to use with_method_overridden
747
+ # once.
748
+ discoverXRI = Proc.new { |identifier|
749
+ return 'XRI'
750
+ }
751
+
752
+ discoverURI = Proc.new { |identifier|
753
+ return 'URI'
754
+ }
755
+
756
+ OpenID.extend(OverrideMethodMixin)
757
+
758
+ OpenID.with_method_overridden(:discover_uri, discoverURI) do
759
+ OpenID.with_method_overridden(:discover_xri, discoverXRI) do
760
+ assert_equal('URI', OpenID.discover('http://woo!'))
761
+ assert_equal('URI', OpenID.discover('not a URL or XRI'))
762
+ assert_equal('XRI', OpenID.discover('xri://=something'))
763
+ assert_equal('XRI', OpenID.discover('=something'))
764
+ end
765
+ end
766
+ end
767
+ end
768
+
769
+ class TestEndpointSupportsType < Test::Unit::TestCase
770
+ def setup
771
+ @endpoint = OpenIDServiceEndpoint.new()
772
+ end
773
+
774
+ def failUnlessSupportsOnly(*types)
775
+ ['foo',
776
+ OPENID_1_1_TYPE,
777
+ OPENID_1_0_TYPE,
778
+ OPENID_2_0_TYPE,
779
+ OPENID_IDP_2_0_TYPE].each { |t|
780
+ if types.member?(t)
781
+ assert(@endpoint.supports_type(t),
782
+ sprintf("Must support %s", t))
783
+ else
784
+ assert(!@endpoint.supports_type(t),
785
+ sprintf("Shouldn't support %s", t))
786
+ end
787
+ }
788
+ end
789
+
790
+ def test_supportsNothing
791
+ failUnlessSupportsOnly()
792
+ end
793
+
794
+ def test_openid2
795
+ @endpoint.type_uris = [OPENID_2_0_TYPE]
796
+ failUnlessSupportsOnly(OPENID_2_0_TYPE)
797
+ end
798
+
799
+ def test_openid2provider
800
+ @endpoint.type_uris = [OPENID_IDP_2_0_TYPE]
801
+ failUnlessSupportsOnly(OPENID_IDP_2_0_TYPE,
802
+ OPENID_2_0_TYPE)
803
+ end
804
+
805
+ def test_openid1_0
806
+ @endpoint.type_uris = [OPENID_1_0_TYPE]
807
+ failUnlessSupportsOnly(OPENID_1_0_TYPE)
808
+ end
809
+
810
+ def test_openid1_1
811
+ @endpoint.type_uris = [OPENID_1_1_TYPE]
812
+ failUnlessSupportsOnly(OPENID_1_1_TYPE)
813
+ end
814
+
815
+ def test_multiple
816
+ @endpoint.type_uris = [OPENID_1_1_TYPE,
817
+ OPENID_2_0_TYPE]
818
+ failUnlessSupportsOnly(OPENID_1_1_TYPE,
819
+ OPENID_2_0_TYPE)
820
+ end
821
+
822
+ def test_multipleWithProvider
823
+ @endpoint.type_uris = [OPENID_1_1_TYPE,
824
+ OPENID_2_0_TYPE,
825
+ OPENID_IDP_2_0_TYPE]
826
+ failUnlessSupportsOnly(OPENID_1_1_TYPE,
827
+ OPENID_2_0_TYPE,
828
+ OPENID_IDP_2_0_TYPE)
829
+ end
830
+ end
831
+
832
+ class TestEndpointDisplayIdentifier < Test::Unit::TestCase
833
+ def test_strip_fragment
834
+ @endpoint = OpenIDServiceEndpoint.new()
835
+ @endpoint.claimed_id = 'http://recycled.invalid/#123'
836
+ assert_equal 'http://recycled.invalid/', @endpoint.display_identifier
837
+ end
838
+ end
839
+
840
+
841
+ class TestNormalizeURL < Test::Unit::TestCase
842
+ def test_no_host
843
+ assert_raise(DiscoveryFailure) {
844
+ OpenID::normalize_url('http:///too-many.invalid/slashes')
845
+ }
846
+ end
847
+ end
848
+ end