nov-ruby-openid 2.1.9

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