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,165 @@
1
+ require 'test/unit'
2
+ require 'openid/kvform'
3
+ require 'openid/util'
4
+ require 'util'
5
+
6
+ include OpenID
7
+
8
+ class KVFormTests < Test::Unit::TestCase
9
+ include OpenID::TestUtil
10
+
11
+ def test_kvdict
12
+ [
13
+ # (kvform, parsed dictionary, expected warnings)
14
+ ["", {}, 0],
15
+ ["\n \n \n", {}, 0],
16
+ ["college:harvey mudd\n", {"college" => "harvey mudd"}, 0],
17
+ ["city:claremont\nstate:CA\n",
18
+ {"city" => "claremont", "state" => "CA"}, 0],
19
+ ["is_valid:true\ninvalidate_handle:{HMAC-SHA1:2398410938412093}\n",
20
+ {"is_valid" => "true",
21
+ "invalidate_handle" => "{HMAC-SHA1:2398410938412093}"}, 0],
22
+
23
+ # Warnings from lines with no colon:
24
+ ["x\n", {}, 1],
25
+ ["x\nx\n", {}, 2],
26
+ ["East is least\n", {}, 1],
27
+
28
+ # But not from blank lines (because LJ generates them)
29
+ ["x\n\n", {}, 1],
30
+
31
+ # Warning from empty key
32
+ [":\n", {''=>''}, 1],
33
+ [":missing key\n", {''=>'missing key'}, 1],
34
+
35
+ # Warnings from leading or trailing whitespace in key or value
36
+ [" street:foothill blvd\n", {"street"=>"foothill blvd"}, 1],
37
+ ["major: computer science\n", {"major"=>"computer science"}, 1],
38
+ [" dorm : east \n", {"dorm"=>"east"}, 2],
39
+
40
+ # Warnings from missing trailing newline
41
+ ["e^(i*pi)+1:0", {"e^(i*pi)+1" => "0"}, 1],
42
+ ["east:west\nnorth:south", {"east"=>"west", "north"=>"south"}, 1],
43
+ ].each { |case_|
44
+ _run_kvdictTest(case_)
45
+ }
46
+ end
47
+
48
+ def _run_kvdictTest(case_)
49
+ kv, dct, warnings = case_
50
+
51
+ d = nil
52
+ d2 = nil
53
+ assert_log_line_count(warnings) {
54
+ # Convert KVForm to dict
55
+ d = Util.kv_to_dict(kv)
56
+
57
+ # Strict mode should raise KVFormError instead of logging
58
+ # messages
59
+ if warnings > 0
60
+ assert_raise(KVFormError) do
61
+ Util.kv_to_seq(kv, true)
62
+ end
63
+ end
64
+
65
+ # make sure it parses to expected dict
66
+ assert_equal(dct, d)
67
+ }
68
+
69
+ # Convert back to KVForm and round-trip back to dict to make sure
70
+ # that *** dict -> kv -> dict is identity. ***
71
+ kv = Util.dict_to_kv(d)
72
+
73
+ silence_logging {
74
+ d2 = Util.kv_to_dict(kv)
75
+ }
76
+
77
+ assert_equal(d, d2)
78
+ end
79
+
80
+ def test_kvseq
81
+ [
82
+ [[], "", 0],
83
+
84
+ [[["openid", "useful"], ["a", "b"]], "openid:useful\na:b\n", 0],
85
+
86
+ # Warnings about leading whitespace
87
+ [[[" openid", "useful"], ["a", "b"]], " openid:useful\na:b\n", 2],
88
+
89
+ # Warnings about leading and trailing whitespace
90
+ [[[" openid ", " useful "],
91
+ [" a ", " b "]], " openid : useful \n a : b \n", 8],
92
+
93
+ # warnings about leading and trailing whitespace, but not about
94
+ # internal whitespace.
95
+ [[[" open id ", " use ful "],
96
+ [" a ", " b "]], " open id : use ful \n a : b \n", 8],
97
+
98
+ [[["foo", "bar"]], "foo:bar\n", 0],
99
+ ].each { |case_|
100
+ _run_kvseqTest(case_)
101
+ }
102
+ end
103
+
104
+ def _cleanSeq(seq)
105
+ # Create a new sequence by stripping whitespace from start and end
106
+ # of each value of each pair
107
+ seq.collect { |k, v| [k.strip(), v.strip()] }
108
+ end
109
+
110
+ def _run_kvseqTest(case_)
111
+ seq, kvform, warnings = case_
112
+
113
+ assert_log_line_count(warnings) {
114
+ # seq serializes to expected kvform
115
+ actual = Util.seq_to_kv(seq)
116
+
117
+ assert_equal(kvform, actual)
118
+ assert actual.is_a?(String)
119
+
120
+ # Strict mode should raise KVFormError instead of logging
121
+ # messages
122
+ if warnings > 0
123
+ assert_raise(KVFormError) do
124
+ Util.seq_to_kv(seq, true)
125
+ end
126
+ end
127
+
128
+ # Parse back to sequence. Expected to be unchanged, except
129
+ # stripping whitespace from start and end of values
130
+ # (i. e. ordering, case, and internal whitespace is preserved)
131
+ seq = Util.kv_to_seq(actual)
132
+ clean_seq = _cleanSeq(seq)
133
+
134
+ assert_equal(seq, clean_seq)
135
+ }
136
+ end
137
+
138
+ def test_kvexc
139
+ [
140
+ [["openid", "use\nful"]],
141
+ [["open\nid", "useful"]],
142
+ [["open\nid", "use\nful"]],
143
+ [["open:id", "useful"]],
144
+ [["foo", "bar"], ["ba\n d", "seed"]],
145
+ [["foo", "bar"], ["bad:", "seed"]],
146
+ ].each { |case_|
147
+ _run_kvexcTest(case_)
148
+ }
149
+ end
150
+
151
+ def _run_kvexcTest(case_)
152
+ seq = case_
153
+
154
+ assert_raise(KVFormError) do
155
+ Util.seq_to_kv(seq)
156
+ end
157
+ end
158
+
159
+ def test_convert
160
+ assert_log_line_count(2) {
161
+ result = Util.seq_to_kv([[1, 1]])
162
+ assert_equal(result, "1:1\n")
163
+ }
164
+ end
165
+ end
@@ -0,0 +1,65 @@
1
+ require "openid/kvpost"
2
+ require "openid/kvform"
3
+ require "openid/message"
4
+ require "test/unit"
5
+ require 'testutil'
6
+
7
+ module OpenID
8
+ class KVPostTestCase < Test::Unit::TestCase
9
+ include FetcherMixin
10
+
11
+ def mk_resp(status, resp_hash)
12
+ return MockResponse.new(status, Util.dict_to_kv(resp_hash))
13
+ end
14
+
15
+ def test_msg_from_http_resp_success
16
+ resp = mk_resp(200, {'mode' => 'seitan'})
17
+ msg = Message.from_http_response(resp, 'http://invalid/')
18
+ assert_equal({'openid.mode' => 'seitan'}, msg.to_post_args)
19
+ end
20
+
21
+ def test_400
22
+ args = {'error' => 'I ate too much cheese',
23
+ 'error_code' => 'sadness'}
24
+ resp = mk_resp(400, args)
25
+ begin
26
+ val = Message.from_http_response(resp, 'http://invalid/')
27
+ rescue ServerError => why
28
+ assert_equal(why.error_text, 'I ate too much cheese')
29
+ assert_equal(why.error_code, 'sadness')
30
+ assert_equal(why.message.to_args, args)
31
+ else
32
+ fail("Expected exception. Got: #{val}")
33
+ end
34
+ end
35
+
36
+ def test_500
37
+ args = {'error' => 'I ate too much cheese',
38
+ 'error_code' => 'sadness'}
39
+ resp = mk_resp(500, args)
40
+ assert_raises(HTTPStatusError) {
41
+ Message.from_http_response(resp, 'http://invalid')
42
+ }
43
+ end
44
+
45
+ def make_kv_post_with_response(status, args)
46
+ resp = mk_resp(status, args)
47
+ mock_fetcher = Class.new do
48
+ define_method(:fetch) do |url, body, xxx, yyy|
49
+ resp
50
+ end
51
+ end
52
+ fetcher = mock_fetcher.new
53
+
54
+ with_fetcher(mock_fetcher.new) do
55
+ OpenID.make_kv_post(Message.from_openid_args(args), 'http://invalid/')
56
+ end
57
+ end
58
+
59
+ def test_make_kv_post
60
+ assert_raises(HTTPStatusError) {
61
+ make_kv_post_with_response(500, {})
62
+ }
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,101 @@
1
+ require 'test/unit'
2
+ require 'testutil'
3
+ require 'openid/consumer/html_parse'
4
+
5
+ class LinkParseTestCase < Test::Unit::TestCase
6
+ include OpenID::TestDataMixin
7
+
8
+ def attr_cmp(expected, found)
9
+ e = expected.to_a.sort
10
+ f = found.to_a.sort
11
+ while (ep = e.shift)
12
+ ek, ev = ep
13
+ fk, fv = f.shift
14
+ ok = false
15
+ while ek[-1] == '*'[0] # optional entry detected
16
+ if fk == ek[0...-1] and fv==ev # optional entry found
17
+ ok = true
18
+ break
19
+ else # not found. okay, move on to next expected pair
20
+ ek, ev = e.shift
21
+ end
22
+ if ek.nil?
23
+ if fk == nil
24
+ ok = true
25
+ end
26
+ break
27
+ end
28
+ end
29
+ next if ok
30
+ next if fk == ek and fv == ev
31
+ return false
32
+ end
33
+ return f.empty?
34
+ end
35
+
36
+ def test_attrcmp
37
+ good = [
38
+ [{'foo' => 'bar'},{'foo' => 'bar'}],
39
+ [{'foo*' => 'bar'},{'foo' => 'bar'}],
40
+ [{'foo' => 'bar', 'bam*' => 'baz'},{'foo' => 'bar'}],
41
+ [{'foo' => 'bar', 'bam*' => 'baz', 'tak' => 'tal'},
42
+ {'foo' => 'bar', 'tak' => 'tal'}],
43
+ ]
44
+ bad = [
45
+ [{},{'foo' => 'bar'}],
46
+ [{'foo' => 'bar'}, {'bam' => 'baz'}],
47
+ [{'foo' => 'bar'}, {}],
48
+ [{'foo*' => 'bar'},{'foo*' => 'bar'}],
49
+ [{'foo' => 'bar', 'tak' => 'tal'}, {'foo' => 'bar'}]
50
+ ]
51
+ good.each{|c|assert(attr_cmp(c[0],c[1]),c.inspect)}
52
+ bad.each{|c|assert(!attr_cmp(c[0],c[1]),c.inspect)}
53
+
54
+ end
55
+
56
+ def test_linkparse
57
+ cases = read_data_file('linkparse.txt', false).split("\n\n\n")
58
+
59
+ numtests = nil
60
+ testnum = 0
61
+ cases.each {|c|
62
+ headers, html = c.split("\n\n",2)
63
+ expected_links = []
64
+ name = ""
65
+ testnum += 1
66
+ headers.split("\n").each{|h|
67
+ k,v = h.split(":",2)
68
+ v = '' if v.nil?
69
+ if k == "Num Tests"
70
+ assert(numtests.nil?, "datafile parsing error: there can be only one NumTests")
71
+ numtests = v.to_i
72
+ testnum = 0
73
+ next
74
+ elsif k == "Name"
75
+ name = v.strip
76
+ elsif k == "Link" or k == "Link*"
77
+ attrs = {}
78
+ v.strip.split.each{|a|
79
+ kk,vv = a.split('=')
80
+ attrs[kk]=vv
81
+ }
82
+ expected_links << [k== "Link*", attrs]
83
+ else
84
+ assert(false, "datafile parsing error: bad header #{h}")
85
+ end
86
+ }
87
+ links = OpenID::parse_link_attrs(html)
88
+
89
+ found = links.dup
90
+ expected = expected_links.dup
91
+ while(fl = found.shift)
92
+ optional, el = expected.shift
93
+ while optional and !attr_cmp(el, fl) and not expected.empty?
94
+ optional, el = expected.shift
95
+ end
96
+ assert(attr_cmp(el,fl), "#{name}: #{fl.inspect} does not match #{el.inspect}")
97
+ end
98
+ }
99
+ assert_equal(numtests, testnum, "Number of tests")
100
+ end
101
+ end
@@ -0,0 +1,1116 @@
1
+ # last synced with Python openid.test.test_message on 6/29/2007.
2
+
3
+ require 'test/unit'
4
+ require 'util'
5
+ require 'openid/message'
6
+
7
+ require 'rexml/document'
8
+
9
+ module OpenID
10
+ module GetArgsMixin
11
+
12
+ # Tests a standard set of behaviors of Message.get_arg with
13
+ # variations on handling defaults.
14
+ def get_arg_tests(ns, key, expected=nil)
15
+ assert_equal(expected, @m.get_arg(ns, key))
16
+
17
+ if expected.nil?
18
+ assert_equal(@m.get_arg(ns, key, :a_default), :a_default)
19
+ assert_raise(Message::KeyNotFound) { @m.get_arg(ns, key, NO_DEFAULT) }
20
+ else
21
+ assert_equal(@m.get_arg(ns, key, :a_default), expected)
22
+ assert_equal(@m.get_arg(ns, key, NO_DEFAULT), expected)
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+
29
+ class EmptyMessageTestCase < Test::Unit::TestCase
30
+ include GetArgsMixin
31
+
32
+ def setup
33
+ @m = Message.new
34
+ end
35
+
36
+ def test_get_aliased_arg_no_default
37
+ assert_raises(Message::KeyNotFound) do
38
+ @m.get_aliased_arg('ns.pork', NO_DEFAULT)
39
+ end
40
+
41
+ ns_uri = "urn:pork"
42
+ @m.namespaces.add_alias(ns_uri, 'pork_alias')
43
+
44
+ # Should return ns_uri.
45
+ assert_equal(ns_uri, @m.get_aliased_arg('ns.pork_alias', NO_DEFAULT))
46
+ end
47
+
48
+ def test_to_post_args
49
+ assert_equal({}, @m.to_post_args)
50
+ end
51
+
52
+ def test_to_args
53
+ assert_equal({}, @m.to_args)
54
+ end
55
+
56
+ def test_to_kvform
57
+ assert_equal('', @m.to_kvform)
58
+ end
59
+
60
+ def test_from_kvform
61
+ kvform = "foo:bar\none:two\n"
62
+ args = {'foo' => 'bar', 'one' => 'two'}
63
+ expected_result = Message.from_openid_args(args)
64
+
65
+ assert_equal(expected_result, Message.from_kvform(kvform))
66
+ end
67
+
68
+ def test_to_url_encoded
69
+ assert_equal('', @m.to_url_encoded)
70
+ end
71
+
72
+ def test_to_url
73
+ base_url = 'http://base.url/'
74
+ assert_equal(base_url, @m.to_url(base_url))
75
+ end
76
+
77
+ def test_get_openid
78
+ assert_equal(nil, @m.get_openid_namespace)
79
+ end
80
+
81
+ def test_get_key_openid
82
+ assert_raise(UndefinedOpenIDNamespace) {
83
+ @m.get_key(OPENID_NS, nil)
84
+ }
85
+ end
86
+
87
+ def test_get_key_bare
88
+ assert_equal('foo', @m.get_key(BARE_NS, 'foo'))
89
+ end
90
+
91
+ def test_get_key_ns1
92
+ assert_equal(nil, @m.get_key(OPENID1_NS, 'foo'))
93
+ end
94
+
95
+ def test_get_key_ns2
96
+ assert_equal(nil, @m.get_key(OPENID2_NS, 'foo'))
97
+ end
98
+
99
+ def test_get_key_ns3
100
+ assert_equal(nil, @m.get_key('urn:something-special', 'foo'))
101
+ end
102
+
103
+ def test_has_key
104
+ assert_raise(UndefinedOpenIDNamespace) {
105
+ @m.has_key?(OPENID_NS, 'foo')
106
+ }
107
+ end
108
+
109
+ def test_has_key_bare
110
+ assert_equal(false, @m.has_key?(BARE_NS, 'foo'))
111
+ end
112
+
113
+ def test_has_key_ns1
114
+ assert_equal(false, @m.has_key?(OPENID1_NS, 'foo'))
115
+ end
116
+
117
+ def test_has_key_ns2
118
+ assert_equal(false, @m.has_key?(OPENID2_NS, 'foo'))
119
+ end
120
+
121
+ def test_has_key_ns3
122
+ assert_equal(false, @m.has_key?('urn:xxx', 'foo'))
123
+ end
124
+
125
+ def test_get_arg
126
+ assert_raise(UndefinedOpenIDNamespace) {
127
+ @m.get_args(OPENID_NS)
128
+ }
129
+ end
130
+
131
+ def test_get_arg_bare
132
+ get_arg_tests(ns=BARE_NS, key='foo')
133
+ end
134
+
135
+ def test_get_arg_ns1
136
+ get_arg_tests(ns=OPENID1_NS, key='foo')
137
+ end
138
+
139
+ def test_get_arg_ns2
140
+ get_arg_tests(ns=OPENID2_NS, key='foo')
141
+ end
142
+
143
+ def test_get_arg_ns3
144
+ get_arg_tests(ns='urn:nothing-significant', key='foo')
145
+ end
146
+
147
+ def test_get_args
148
+ assert_raise(UndefinedOpenIDNamespace) {
149
+ @m.get_args(OPENID_NS)
150
+ }
151
+ end
152
+
153
+ def test_get_args_bare
154
+ assert_equal({}, @m.get_args(BARE_NS))
155
+ end
156
+
157
+ def test_get_args_ns1
158
+ assert_equal({}, @m.get_args(OPENID1_NS))
159
+ end
160
+
161
+ def test_get_args_ns2
162
+ assert_equal({}, @m.get_args(OPENID2_NS))
163
+ end
164
+
165
+ def test_get_args_ns3
166
+ assert_equal({}, @m.get_args('urn:xxx'))
167
+ end
168
+
169
+ def test_update_args
170
+ assert_raise(UndefinedOpenIDNamespace) {
171
+ @m.update_args(OPENID_NS, {'does not'=>'matter'})
172
+ }
173
+ end
174
+
175
+ def _test_update_args_ns(ns)
176
+ updates = {
177
+ 'camper van beethoven' => 'david l',
178
+ 'magnolia electric, co' => 'jason m'
179
+ }
180
+ assert_equal({}, @m.get_args(ns))
181
+ @m.update_args(ns, updates)
182
+ assert_equal(updates, @m.get_args(ns))
183
+ end
184
+
185
+ def test_update_args_bare
186
+ _test_update_args_ns(BARE_NS)
187
+ end
188
+ def test_update_args_ns1
189
+ _test_update_args_ns(OPENID1_NS)
190
+ end
191
+ def test_update_args_ns2
192
+ _test_update_args_ns(OPENID2_NS)
193
+ end
194
+ def test_update_args_ns3
195
+ _test_update_args_ns('urn:xxx')
196
+ end
197
+
198
+ def test_set_arg
199
+ assert_raise(UndefinedOpenIDNamespace) {
200
+ @m.set_arg(OPENID_NS,'does not','matter')
201
+ }
202
+ end
203
+
204
+ def _test_set_arg_ns(ns)
205
+ key = 'Camper Van Beethoven'
206
+ value = 'David Lowery'
207
+ assert_equal(nil, @m.get_arg(ns, key))
208
+ @m.set_arg(ns, key, value)
209
+ assert_equal(value, @m.get_arg(ns, key))
210
+ end
211
+
212
+ def test_set_arg_bare
213
+ _test_set_arg_ns(BARE_NS)
214
+ end
215
+ def test_set_arg_ns1
216
+ _test_set_arg_ns(OPENID1_NS)
217
+ end
218
+ def test_set_arg_ns2
219
+ _test_set_arg_ns(OPENID2_NS)
220
+ end
221
+ def test_set_arg_ns3
222
+ _test_set_arg_ns('urn:xxx')
223
+ end
224
+
225
+ def test_del_arg
226
+ assert_raise(UndefinedOpenIDNamespace) {
227
+ @m.set_arg(OPENID_NS, 'does not', 'matter')
228
+ }
229
+ end
230
+
231
+ def _test_del_arg_ns(ns)
232
+ key = 'Fleeting Joys'
233
+ assert_equal(nil, @m.del_arg(ns, key))
234
+ end
235
+
236
+ def test_del_arg_bare
237
+ _test_del_arg_ns(BARE_NS)
238
+ end
239
+ def test_del_arg_ns1
240
+ _test_del_arg_ns(OPENID1_NS)
241
+ end
242
+ def test_del_arg_ns2
243
+ _test_del_arg_ns(OPENID2_NS)
244
+ end
245
+ def test_del_arg_ns3
246
+ _test_del_arg_ns('urn:xxx')
247
+ end
248
+
249
+ def test_isOpenID1
250
+ assert_equal(false, @m.is_openid1)
251
+ end
252
+
253
+ def test_isOpenID2
254
+ assert_equal(false, @m.is_openid2)
255
+ end
256
+
257
+ def test_set_openid_namespace
258
+ assert_raise(InvalidOpenIDNamespace) {
259
+ @m.set_openid_namespace('http://invalid/', false)
260
+ }
261
+ end
262
+ end
263
+
264
+ class OpenID1MessageTest < Test::Unit::TestCase
265
+ include GetArgsMixin
266
+
267
+ def setup
268
+ @m = Message.from_post_args({'openid.mode' => 'error',
269
+ 'openid.error' => 'unit test'})
270
+ end
271
+
272
+ def test_has_openid_ns
273
+ assert_equal(OPENID1_NS, @m.get_openid_namespace)
274
+ assert_equal(OPENID1_NS,
275
+ @m.namespaces.get_namespace_uri(NULL_NAMESPACE))
276
+ end
277
+
278
+ def test_get_aliased_arg
279
+ assert_equal('error', @m.get_aliased_arg('mode'))
280
+ end
281
+
282
+ def test_get_aliased_arg_ns
283
+ assert_equal(OPENID1_NS, @m.get_aliased_arg('ns'))
284
+ end
285
+
286
+ def test_get_aliased_arg_with_ns
287
+ @m = Message.from_post_args(
288
+ {'openid.mode' => 'error',
289
+ 'openid.error' => 'unit test',
290
+ 'openid.ns.invalid' => 'http://invalid/',
291
+ 'openid.invalid.stuff' => 'things',
292
+ 'openid.invalid.stuff.blinky' => 'powerplant',
293
+ })
294
+ assert_equal('http://invalid/', @m.get_aliased_arg('ns.invalid'))
295
+ assert_equal('things', @m.get_aliased_arg('invalid.stuff'))
296
+ assert_equal('powerplant', @m.get_aliased_arg('invalid.stuff.blinky'))
297
+ end
298
+
299
+ def test_get_aliased_arg_with_ns_default
300
+ @m = Message.from_post_args({})
301
+ assert_equal('monkeys!', @m.get_aliased_arg('ns.invalid',
302
+ default="monkeys!"))
303
+ end
304
+
305
+ def test_to_post_args
306
+ assert_equal({'openid.mode' => 'error',
307
+ 'openid.error' => 'unit test'},
308
+ @m.to_post_args)
309
+ end
310
+
311
+ def test_to_post_args_ns
312
+ invalid_ns = 'http://invalid/'
313
+ @m.namespaces.add_alias(invalid_ns, 'foos')
314
+ @m.set_arg(invalid_ns, 'ball', 'awesome')
315
+ @m.set_arg(BARE_NS, 'xey', 'value')
316
+ assert_equal({'openid.mode' => 'error',
317
+ 'openid.error' => 'unit test',
318
+ 'openid.foos.ball' => 'awesome',
319
+ 'xey' => 'value',
320
+ 'openid.ns.foos' => 'http://invalid/'
321
+ }, @m.to_post_args)
322
+ end
323
+
324
+ def test_to_args
325
+ assert_equal({'mode' => 'error',
326
+ 'error' => 'unit test'},
327
+ @m.to_args)
328
+ end
329
+
330
+ def test_to_kvform
331
+ assert_equal("error:unit test\nmode:error\n",
332
+ @m.to_kvform)
333
+ end
334
+
335
+ def test_to_url_encoded
336
+ assert_equal('openid.error=unit+test&openid.mode=error',
337
+ @m.to_url_encoded)
338
+ end
339
+
340
+ def test_to_url
341
+ base_url = 'http://base.url/'
342
+ actual = @m.to_url(base_url)
343
+ actual_base = actual[0...base_url.length]
344
+ assert_equal(base_url, actual_base)
345
+ assert_equal('?', actual[base_url.length].chr)
346
+ query = actual[base_url.length+1..-1]
347
+ assert_equal({'openid.mode'=>['error'],'openid.error'=>['unit test']},
348
+ CGI.parse(query))
349
+ end
350
+
351
+ def test_get_openid
352
+ assert_equal(OPENID1_NS, @m.get_openid_namespace)
353
+ end
354
+
355
+ def test_get_key_openid
356
+ assert_equal('openid.mode', @m.get_key(OPENID_NS, 'mode'))
357
+ end
358
+
359
+ def test_get_key_bare
360
+ assert_equal('mode', @m.get_key(BARE_NS, 'mode'))
361
+ end
362
+
363
+ def test_get_key_ns1
364
+ assert_equal('openid.mode', @m.get_key(OPENID1_NS, 'mode'))
365
+ end
366
+
367
+ def test_get_key_ns2
368
+ assert_equal(nil, @m.get_key(OPENID2_NS, 'mode'))
369
+ end
370
+
371
+ def test_get_key_ns3
372
+ assert_equal(nil, @m.get_key('urn:xxx', 'mode'))
373
+ end
374
+
375
+ def test_has_key
376
+ assert_equal(true, @m.has_key?(OPENID_NS, 'mode'))
377
+ end
378
+ def test_has_key_bare
379
+ assert_equal(false, @m.has_key?(BARE_NS, 'mode'))
380
+ end
381
+ def test_has_key_ns1
382
+ assert_equal(true, @m.has_key?(OPENID1_NS, 'mode'))
383
+ end
384
+ def test_has_key_ns2
385
+ assert_equal(false, @m.has_key?(OPENID2_NS, 'mode'))
386
+ end
387
+ def test_has_key_ns3
388
+ assert_equal(false, @m.has_key?('urn:xxx', 'mode'))
389
+ end
390
+
391
+ def test_get_arg
392
+ assert_equal('error', @m.get_arg(OPENID_NS, 'mode'))
393
+ end
394
+
395
+ def test_get_arg_bare
396
+ get_arg_tests(ns=BARE_NS, key='mode')
397
+ end
398
+
399
+ def test_get_arg_ns
400
+ get_arg_tests(ns=OPENID_NS, key='mode', expected='error')
401
+ end
402
+
403
+ def test_get_arg_ns1
404
+ get_arg_tests(ns=OPENID1_NS, key='mode', expected='error')
405
+ end
406
+
407
+ def test_get_arg_ns2
408
+ get_arg_tests(ns=OPENID2_NS, key='mode')
409
+ end
410
+
411
+ def test_get_arg_ns3
412
+ get_arg_tests(ns='urn:nothing-significant', key='mode')
413
+ end
414
+
415
+ def test_get_args
416
+ assert_equal({'mode'=>'error','error'=>'unit test'},
417
+ @m.get_args(OPENID_NS))
418
+ end
419
+ def test_get_args_bare
420
+ assert_equal({}, @m.get_args(BARE_NS))
421
+ end
422
+ def test_get_args_ns1
423
+ assert_equal({'mode'=>'error','error'=>'unit test'},
424
+ @m.get_args(OPENID1_NS))
425
+ end
426
+ def test_get_args_ns2
427
+ assert_equal({}, @m.get_args(OPENID2_NS))
428
+ end
429
+ def test_get_args_ns3
430
+ assert_equal({}, @m.get_args('urn:xxx'))
431
+ end
432
+
433
+ def _test_update_args_ns(ns, before=nil)
434
+ if before.nil?
435
+ before = {}
436
+ end
437
+ update_args = {
438
+ 'Camper van Beethoven'=>'David Lowery',
439
+ 'Magnolia Electric Co.'=>'Jason Molina'
440
+ }
441
+ assert_equal(before, @m.get_args(ns))
442
+ @m.update_args(ns, update_args)
443
+ after = before.dup
444
+ after.update(update_args)
445
+ assert_equal(after, @m.get_args(ns))
446
+ end
447
+
448
+ def test_update_args
449
+ _test_update_args_ns(OPENID_NS, {'mode'=>'error','error'=>'unit test'})
450
+ end
451
+ def test_update_args_bare
452
+ _test_update_args_ns(BARE_NS)
453
+ end
454
+ def test_update_args_ns1
455
+ _test_update_args_ns(OPENID1_NS, {'mode'=>'error','error'=>'unit test'})
456
+ end
457
+ def test_update_args_ns2
458
+ _test_update_args_ns(OPENID2_NS)
459
+ end
460
+ def test_update_args_ns3
461
+ _test_update_args_ns('urn:xxx')
462
+ end
463
+
464
+ def _test_set_arg_ns(ns)
465
+ key = 'awesometown'
466
+ value = 'funny'
467
+ assert_equal(nil, @m.get_arg(ns,key))
468
+ @m.set_arg(ns, key, value)
469
+ assert_equal(value, @m.get_arg(ns,key))
470
+ end
471
+
472
+ def test_set_arg; _test_set_arg_ns(OPENID_NS); end
473
+ def test_set_arg_bare; _test_set_arg_ns(BARE_NS); end
474
+ def test_set_arg_ns1; _test_set_arg_ns(OPENID1_NS); end
475
+ def test_set_arg_ns2; _test_set_arg_ns(OPENID2_NS); end
476
+ def test_set_arg_ns3; _test_set_arg_ns('urn:xxx'); end
477
+
478
+ def _test_del_arg_ns(ns)
479
+ key = 'marry an'
480
+ value = 'ice cream sandwich'
481
+ @m.set_arg(ns, key, value)
482
+ assert_equal(value, @m.get_arg(ns,key))
483
+ @m.del_arg(ns,key)
484
+ assert_equal(nil, @m.get_arg(ns,key))
485
+ end
486
+
487
+ def test_del_arg; _test_del_arg_ns(OPENID_NS); end
488
+ def test_del_arg_bare; _test_del_arg_ns(BARE_NS); end
489
+ def test_del_arg_ns1; _test_del_arg_ns(OPENID1_NS); end
490
+ def test_del_arg_ns2; _test_del_arg_ns(OPENID2_NS); end
491
+ def test_del_arg_ns3; _test_del_arg_ns('urn:yyy'); end
492
+
493
+ def test_isOpenID1
494
+ assert_equal(true, @m.is_openid1)
495
+ end
496
+
497
+ def test_isOpenID2
498
+ assert_equal(false, @m.is_openid2)
499
+ end
500
+
501
+ def test_equal
502
+ assert_equal(Message.new, Message.new)
503
+ assert_not_equal(Message.new, nil)
504
+ end
505
+
506
+ def test_from_openid_args_undefined_ns
507
+ expected = 'almost.complete'
508
+ msg = Message.from_openid_args({'coverage.is' => expected})
509
+ actual = msg.get_arg(OPENID1_NS, 'coverage.is')
510
+ assert_equal(expected, actual)
511
+ end
512
+
513
+ # XXX: we need to implement the KVForm module before we can fix this
514
+ def TODOtest_from_kvform
515
+ kv = 'foos:ball\n'
516
+ msg = Message.from_kvform(kv)
517
+ assert_equal(msg.get(OPENID1_NS, 'foos'), 'ball')
518
+ end
519
+
520
+ def test_initialize_sets_namespace
521
+ msg = Message.new(OPENID1_NS)
522
+ assert_equal(OPENID1_NS, msg.get_openid_namespace)
523
+ end
524
+ end
525
+
526
+ class OpenID1ExplicitMessageTest < Test::Unit::TestCase
527
+ # XXX - check to make sure the test suite will get built the way this
528
+ # expects.
529
+ def setup
530
+ @m = Message.from_post_args({'openid.mode'=>'error',
531
+ 'openid.error'=>'unit test',
532
+ 'openid.ns'=>OPENID1_NS})
533
+ end
534
+
535
+ def test_to_post_args
536
+ assert_equal({'openid.mode' => 'error',
537
+ 'openid.error' => 'unit test',
538
+ 'openid.ns'=>OPENID1_NS,
539
+ },
540
+ @m.to_post_args)
541
+ end
542
+
543
+ def test_to_post_args_ns
544
+ invalid_ns = 'http://invalid/'
545
+ @m.namespaces.add_alias(invalid_ns, 'foos')
546
+ @m.set_arg(invalid_ns, 'ball', 'awesome')
547
+ @m.set_arg(BARE_NS, 'xey', 'value')
548
+ assert_equal({'openid.mode' => 'error',
549
+ 'openid.error' => 'unit test',
550
+ 'openid.foos.ball' => 'awesome',
551
+ 'xey' => 'value',
552
+ 'openid.ns'=>OPENID1_NS,
553
+ 'openid.ns.foos' => 'http://invalid/'
554
+ }, @m.to_post_args)
555
+ end
556
+
557
+ def test_to_args
558
+ assert_equal({'mode' => 'error',
559
+ 'error' => 'unit test',
560
+ 'ns'=>OPENID1_NS
561
+ },
562
+ @m.to_args)
563
+ end
564
+
565
+ def test_to_kvform
566
+ assert_equal("error:unit test\nmode:error\nns:#{OPENID1_NS}\n",
567
+ @m.to_kvform)
568
+ end
569
+
570
+ def test_to_url_encoded
571
+ assert_equal('openid.error=unit+test&openid.mode=error&openid.ns=http%3A%2F%2Fopenid.net%2Fsignon%2F1.0',
572
+ @m.to_url_encoded)
573
+ end
574
+
575
+ def test_to_url
576
+ base_url = 'http://base.url/'
577
+ actual = @m.to_url(base_url)
578
+ actual_base = actual[0...base_url.length]
579
+ assert_equal(base_url, actual_base)
580
+ assert_equal('?', actual[base_url.length].chr)
581
+ query = actual[base_url.length+1..-1]
582
+ assert_equal({'openid.mode'=>['error'],
583
+ 'openid.error'=>['unit test'],
584
+ 'openid.ns'=>[OPENID1_NS],
585
+ },
586
+ CGI.parse(query))
587
+ end
588
+
589
+
590
+ end
591
+
592
+ class OpenID2MessageTest < Test::Unit::TestCase
593
+ include TestUtil
594
+
595
+ def setup
596
+ @m = Message.from_post_args({'openid.mode'=>'error',
597
+ 'openid.error'=>'unit test',
598
+ 'openid.ns'=>OPENID2_NS})
599
+ @m.set_arg(BARE_NS, 'xey', 'value')
600
+ end
601
+
602
+ def test_to_args_fails
603
+ assert_raises(ArgumentError) {
604
+ @m.to_args
605
+ }
606
+ end
607
+
608
+ def test_fix_ns_non_string
609
+ # Using has_key to invoke _fix_ns since _fix_ns should be private
610
+ assert_raises(ArgumentError) {
611
+ @m.has_key?(:non_string_namespace, "key")
612
+ }
613
+ end
614
+
615
+ def test_fix_ns_non_uri
616
+ # Using has_key to invoke _fix_ns since _fix_ns should be private
617
+ assert_log_matches(/identifiers SHOULD be URIs/) {
618
+ @m.has_key?("foo", "key")
619
+ }
620
+ end
621
+
622
+ def test_fix_ns_sreg_literal
623
+ # Using has_key to invoke _fix_ns since _fix_ns should be private
624
+ assert_log_matches(/identifiers SHOULD be URIs/, /instead of "sreg"/) {
625
+ @m.has_key?("sreg", "key")
626
+ }
627
+ end
628
+
629
+ def test_copy
630
+ n = @m.copy
631
+ assert_equal(@m, n)
632
+ end
633
+
634
+ def test_to_post_args
635
+ assert_equal({'openid.mode' => 'error',
636
+ 'openid.error' => 'unit test',
637
+ 'openid.ns' => OPENID2_NS,
638
+ 'xey' => 'value',
639
+ }, @m.to_post_args)
640
+ end
641
+
642
+ def test_to_post_args_ns
643
+ invalid_ns = 'http://invalid/'
644
+ @m.namespaces.add_alias(invalid_ns, 'foos')
645
+ @m.set_arg(invalid_ns, 'ball', 'awesome')
646
+ assert_equal({'openid.mode' => 'error',
647
+ 'openid.error' => 'unit test',
648
+ 'openid.ns' => OPENID2_NS,
649
+ 'openid.ns.foos' => invalid_ns,
650
+ 'openid.foos.ball' => 'awesome',
651
+ 'xey' => 'value',
652
+ }, @m.to_post_args)
653
+ end
654
+
655
+ def test_to_args
656
+ @m.del_arg(BARE_NS, 'xey')
657
+ assert_equal({'mode' => 'error',
658
+ 'error' => 'unit test',
659
+ 'ns' => OPENID2_NS},
660
+ @m.to_args)
661
+ end
662
+
663
+ def test_to_kvform
664
+ @m.del_arg(BARE_NS, 'xey')
665
+ assert_equal("error:unit test\nmode:error\nns:#{OPENID2_NS}\n",
666
+ @m.to_kvform)
667
+ end
668
+
669
+ def _test_urlencoded(s)
670
+ expected_list = ["openid.error=unit+test",
671
+ "openid.mode=error",
672
+ "openid.ns=#{CGI.escape(OPENID2_NS)}",
673
+ "xey=value"]
674
+ # Hard to do this with string comparison since the mapping doesn't
675
+ # preserve order.
676
+ encoded_list = s.split('&')
677
+ encoded_list.sort!
678
+ assert_equal(expected_list, encoded_list)
679
+ end
680
+
681
+ def test_to_urlencoded
682
+ _test_urlencoded(@m.to_url_encoded)
683
+ end
684
+
685
+ def test_to_url
686
+ base_url = 'http://base.url/'
687
+ actual = @m.to_url(base_url)
688
+ actual_base = actual[0...base_url.length]
689
+ assert_equal(base_url, actual_base)
690
+ assert_equal('?', actual[base_url.length].chr)
691
+ query = actual[base_url.length+1..-1]
692
+ _test_urlencoded(query)
693
+ end
694
+
695
+ def test_get_openid
696
+ assert_equal(OPENID2_NS, @m.get_openid_namespace)
697
+ end
698
+
699
+ def test_get_key_openid
700
+ assert_equal('openid.mode', @m.get_key(OPENID2_NS, 'mode'))
701
+ end
702
+
703
+ def test_get_key_bare
704
+ assert_equal('mode', @m.get_key(BARE_NS, 'mode'))
705
+ end
706
+
707
+ def test_get_key_ns1
708
+ assert_equal(nil, @m.get_key(OPENID1_NS, 'mode'))
709
+ end
710
+
711
+ def test_get_key_ns2
712
+ assert_equal('openid.mode', @m.get_key(OPENID2_NS, 'mode'))
713
+ end
714
+
715
+ def test_get_key_ns3
716
+ assert_equal(nil, @m.get_key('urn:xxx', 'mode'))
717
+ end
718
+
719
+ def test_has_key_openid
720
+ assert_equal(true, @m.has_key?(OPENID_NS,'mode'))
721
+ end
722
+
723
+ def test_has_key_bare
724
+ assert_equal(false, @m.has_key?(BARE_NS,'mode'))
725
+ end
726
+
727
+ def test_has_key_ns1
728
+ assert_equal(false, @m.has_key?(OPENID1_NS,'mode'))
729
+ end
730
+
731
+ def test_has_key_ns2
732
+ assert_equal(true, @m.has_key?(OPENID2_NS,'mode'))
733
+ end
734
+
735
+ def test_has_key_ns3
736
+ assert_equal(false, @m.has_key?('urn:xxx','mode'))
737
+ end
738
+
739
+ # XXX - getArgTest
740
+ def test_get_arg_openid
741
+ assert_equal('error', @m.get_arg(OPENID_NS,'mode'))
742
+ end
743
+
744
+ def test_get_arg_bare
745
+ assert_equal(nil, @m.get_arg(BARE_NS,'mode'))
746
+ end
747
+
748
+ def test_get_arg_ns1
749
+ assert_equal(nil, @m.get_arg(OPENID1_NS,'mode'))
750
+ end
751
+
752
+ def test_get_arg_ns2
753
+ assert_equal('error', @m.get_arg(OPENID2_NS,'mode'))
754
+ end
755
+
756
+ def test_get_arg_ns3
757
+ assert_equal(nil, @m.get_arg('urn:bananastand','mode'))
758
+ end
759
+
760
+ def test_get_args_openid
761
+ assert_equal({'mode'=>'error','error'=>'unit test'},
762
+ @m.get_args(OPENID_NS))
763
+ end
764
+
765
+ def test_get_args_bare
766
+ assert_equal({'xey'=>'value'},
767
+ @m.get_args(BARE_NS))
768
+ end
769
+
770
+ def test_get_args_ns1
771
+ assert_equal({},
772
+ @m.get_args(OPENID1_NS))
773
+ end
774
+
775
+ def test_get_args_ns2
776
+ assert_equal({'mode'=>'error','error'=>'unit test'},
777
+ @m.get_args(OPENID2_NS))
778
+ end
779
+
780
+ def test_get_args_ns3
781
+ assert_equal({},
782
+ @m.get_args('urn:loose seal'))
783
+ end
784
+
785
+ def _test_update_args_ns(ns, before=nil)
786
+ before = {} unless before
787
+ update_args = {'aa'=>'bb','cc'=>'dd'}
788
+
789
+ assert_equal(before, @m.get_args(ns))
790
+ @m.update_args(ns, update_args)
791
+ after = before.dup
792
+ after.update(update_args)
793
+ assert_equal(after, @m.get_args(ns))
794
+ end
795
+
796
+ def test_update_args_openid
797
+ _test_update_args_ns(OPENID_NS, {'mode'=>'error','error'=>'unit test'})
798
+ end
799
+
800
+ def test_update_args_bare
801
+ _test_update_args_ns(BARE_NS, {'xey'=>'value'})
802
+ end
803
+
804
+ def test_update_args_ns1
805
+ _test_update_args_ns(OPENID1_NS)
806
+ end
807
+
808
+ def test_update_args_ns2
809
+ _test_update_args_ns(OPENID2_NS, {'mode'=>'error','error'=>'unit test'})
810
+ end
811
+
812
+ def test_update_args_ns3
813
+ _test_update_args_ns('urn:sven')
814
+ end
815
+
816
+ def _test_set_arg_ns(ns)
817
+ key = "logan's"
818
+ value = "run"
819
+ assert_equal(nil, @m.get_arg(ns,key))
820
+ @m.set_arg(ns, key, value)
821
+ assert_equal(value, @m.get_arg(ns,key))
822
+ end
823
+
824
+ def test_set_arg_openid; _test_set_arg_ns(OPENID_NS); end
825
+ def test_set_arg_bare; _test_set_arg_ns(BARE_NS); end
826
+ def test_set_arg_ns1; _test_set_arg_ns(OPENID1_NS); end
827
+ def test_set_arg_ns2; _test_set_arg_ns(OPENID2_NS); end
828
+ def test_set_arg_ns3; _test_set_arg_ns('urn:g'); end
829
+
830
+ def test_bad_alias
831
+ # Make sure dotted aliases and OpenID protocol fields are not allowed
832
+ # as namespace aliases.
833
+
834
+ fields = OPENID_PROTOCOL_FIELDS + ['dotted.alias']
835
+
836
+ fields.each { |f|
837
+ args = {"openid.ns.#{f}" => "blah#{f}",
838
+ "openid.#{f}.foo" => "test#{f}"}
839
+
840
+ # .fromPostArgs covers .fromPostArgs, .fromOpenIDArgs,
841
+ # ._fromOpenIDArgs, and .fromOpenIDArgs (since it calls
842
+ # .fromPostArgs).
843
+ assert_raise(AssertionError) {
844
+ Message.from_post_args(args)
845
+ }
846
+ }
847
+ end
848
+
849
+ def test_from_post_args
850
+ msg = Message.from_post_args({'foos' => 'ball'})
851
+ assert_equal('ball', msg.get_arg(BARE_NS, 'foos'))
852
+ end
853
+
854
+ def _test_del_arg_ns(ns)
855
+ key = 'no'
856
+ value = 'socks'
857
+ assert_equal(nil, @m.get_arg(ns, key))
858
+ @m.set_arg(ns, key, value)
859
+ assert_equal(value, @m.get_arg(ns, key))
860
+ @m.del_arg(ns, key)
861
+ assert_equal(nil, @m.get_arg(ns, key))
862
+ end
863
+
864
+ def test_del_arg_openid; _test_del_arg_ns(OPENID_NS); end
865
+ def test_del_arg_bare; _test_del_arg_ns(BARE_NS); end
866
+ def test_del_arg_ns1; _test_del_arg_ns(OPENID1_NS); end
867
+ def test_del_arg_ns2; _test_del_arg_ns(OPENID2_NS); end
868
+ def test_del_arg_ns3; _test_del_arg_ns('urn:tofu'); end
869
+
870
+ def test_overwrite_extension_arg
871
+ ns = 'urn:unittest_extension'
872
+ key = 'mykey'
873
+ value_1 = 'value_1'
874
+ value_2 = 'value_2'
875
+
876
+ @m.set_arg(ns, key, value_1)
877
+ assert_equal(value_1, @m.get_arg(ns, key))
878
+ @m.set_arg(ns, key, value_2)
879
+ assert_equal(value_2, @m.get_arg(ns, key))
880
+ end
881
+
882
+ def test_argList
883
+ assert_raise(ArgumentError) {
884
+ Message.from_post_args({'arg' => [1, 2, 3]})
885
+ }
886
+ end
887
+
888
+ def test_isOpenID1
889
+ assert_equal(false, @m.is_openid1)
890
+ end
891
+
892
+ def test_isOpenID2
893
+ assert_equal(true, @m.is_openid2)
894
+ end
895
+ end
896
+
897
+ class MessageTest < Test::Unit::TestCase
898
+ def setup
899
+ @postargs = {
900
+ 'openid.ns' => OPENID2_NS,
901
+ 'openid.mode' => 'checkid_setup',
902
+ 'openid.identity' => 'http://bogus.example.invalid:port/',
903
+ 'openid.assoc_handle' => 'FLUB',
904
+ 'openid.return_to' => 'Neverland',
905
+ }
906
+
907
+ @action_url = 'scheme://host:port/path?query'
908
+
909
+ @form_tag_attrs = {
910
+ 'company' => 'janrain',
911
+ 'class' => 'fancyCSS',
912
+ }
913
+
914
+ @submit_text = 'GO!'
915
+
916
+ ### Expected data regardless of input
917
+
918
+ @required_form_attrs = {
919
+ 'accept-charset' => 'UTF-8',
920
+ 'enctype' => 'application/x-www-form-urlencoded',
921
+ 'method' => 'post',
922
+ }
923
+ end
924
+
925
+ def _checkForm(html, message_, action_url,
926
+ form_tag_attrs, submit_text)
927
+ @xml = REXML::Document.new(html)
928
+
929
+ # Get root element
930
+ form = @xml.root
931
+
932
+ # Check required form attributes
933
+ @required_form_attrs.each { |k, v|
934
+ assert(form.attributes[k] == v,
935
+ "Expected '#{v}' for required form attribute '#{k}', got '#{form.attributes[k]}'")
936
+ }
937
+
938
+ # Check extra form attributes
939
+ @form_tag_attrs.each { |k, v|
940
+ # Skip attributes that already passed the required attribute
941
+ # check, since they should be ignored by the form generation
942
+ # code.
943
+ if @required_form_attrs.include?(k)
944
+ continue
945
+ end
946
+
947
+ assert(form.attributes[k] == v,
948
+ "Form attribute '#{k}' should be '#{v}', found '#{form.attributes[k]}'")
949
+
950
+ # Check hidden fields against post args
951
+ hiddens = []
952
+ form.each { |e|
953
+ if (e.is_a?(REXML::Element)) and
954
+ (e.name.upcase() == 'INPUT') and
955
+ (e.attributes['type'].upcase() == 'HIDDEN')
956
+ # For each post arg, make sure there is a hidden with that
957
+ # value. Make sure there are no other hiddens.
958
+ hiddens += [e]
959
+ end
960
+ }
961
+
962
+ message_.to_post_args().each { |name, value|
963
+ success = false
964
+
965
+ hiddens.each { |e|
966
+ if e.attributes['name'] == name
967
+ assert(e.attributes['value'] == value,
968
+ "Expected value of hidden input '#{e.attributes['name']}' " +
969
+ "to be '#{value}', got '#{e.attributes['value']}'")
970
+ success = true
971
+ break
972
+ end
973
+ }
974
+
975
+ if !success
976
+ flunk "Post arg '#{name}' not found in form"
977
+ end
978
+ }
979
+
980
+ hiddens.each { |e|
981
+ assert(message_.to_post_args().keys().include?(e.attributes['name']),
982
+ "Form element for '#{e.attributes['name']}' not in " +
983
+ "original message")
984
+ }
985
+
986
+ # Check action URL
987
+ assert(form.attributes['action'] == action_url,
988
+ "Expected form 'action' to be '#{action_url}', got '#{form.attributes['action']}'")
989
+
990
+ # Check submit text
991
+ submits = []
992
+ form.each { |e|
993
+ if (e.is_a?(REXML::Element)) and
994
+ (e.name.upcase() == 'INPUT') and
995
+ e.attributes['type'].upcase() == 'SUBMIT'
996
+ submits += [e]
997
+ end
998
+ }
999
+
1000
+ assert(submits.length == 1,
1001
+ "Expected only one 'input' with type = 'submit', got #{submits.length}")
1002
+
1003
+ assert(submits[0].attributes['value'] == submit_text,
1004
+ "Expected submit value to be '#{submit_text}', " +
1005
+ "got '#{submits[0].attributes['value']}'")
1006
+ }
1007
+
1008
+ end
1009
+
1010
+ def test_toFormMarkup
1011
+ m = Message.from_post_args(@postargs)
1012
+ html = m.to_form_markup(@action_url, @form_tag_attrs,
1013
+ @submit_text)
1014
+ _checkForm(html, m, @action_url,
1015
+ @form_tag_attrs, @submit_text)
1016
+ end
1017
+
1018
+ def test_overrideMethod
1019
+ # Be sure that caller cannot change form method to GET.
1020
+ m = Message.from_post_args(@postargs)
1021
+
1022
+ tag_attrs = @form_tag_attrs.clone
1023
+ tag_attrs['method'] = 'GET'
1024
+
1025
+ html = m.to_form_markup(@action_url, @form_tag_attrs,
1026
+ @submit_text)
1027
+ _checkForm(html, m, @action_url,
1028
+ @form_tag_attrs, @submit_text)
1029
+ end
1030
+
1031
+ def test_overrideRequired
1032
+ # Be sure that caller CANNOT change the form charset for
1033
+ # encoding type.
1034
+ m = Message.from_post_args(@postargs)
1035
+
1036
+ tag_attrs = @form_tag_attrs.clone
1037
+ tag_attrs['accept-charset'] = 'UCS4'
1038
+ tag_attrs['enctype'] = 'invalid/x-broken'
1039
+
1040
+ html = m.to_form_markup(@action_url, tag_attrs,
1041
+ @submit_text)
1042
+ _checkForm(html, m, @action_url,
1043
+ tag_attrs, @submit_text)
1044
+ end
1045
+ end
1046
+
1047
+ class NamespaceMapTestCase < Test::Unit::TestCase
1048
+
1049
+ def test_onealias
1050
+ nsm = NamespaceMap.new
1051
+ uri = 'http://example.com/foo'
1052
+ _alias = 'foo'
1053
+ nsm.add_alias(uri, _alias)
1054
+ assert_equal(uri, nsm.get_namespace_uri(_alias))
1055
+ assert_equal(_alias, nsm.get_alias(uri))
1056
+ end
1057
+
1058
+
1059
+ def test_iteration
1060
+ nsm = NamespaceMap.new
1061
+ uripat = "http://example.com/foo%i"
1062
+ nsm.add(uripat % 0)
1063
+
1064
+ (1..23).each { |i|
1065
+ assert_equal(false, nsm.member?(uripat % i))
1066
+ nsm.add(uripat % i)
1067
+ }
1068
+ nsm.each { |uri, _alias|
1069
+ assert_equal(uri[22..-1], _alias[3..-1])
1070
+ }
1071
+
1072
+ nsm = NamespaceMap.new
1073
+ alias_ = 'bogus'
1074
+ uri = 'urn:bogus'
1075
+
1076
+ nsm.add_alias(uri, alias_)
1077
+
1078
+ assert_equal(nsm.aliases(), [alias_])
1079
+ assert_equal(nsm.namespace_uris(), [uri])
1080
+ end
1081
+
1082
+ def test_register_default_alias
1083
+ invalid_ns = 'http://invalid/'
1084
+ alias_ = 'invalid'
1085
+ Message.register_namespace_alias(invalid_ns, alias_)
1086
+ # Doing it again doesn't raise an exception
1087
+ Message.register_namespace_alias(invalid_ns, alias_)
1088
+
1089
+ # Once it's registered, you can't register it again
1090
+ assert_raises(NamespaceAliasRegistrationError) {
1091
+ Message.register_namespace_alias(invalid_ns, 'another_alias')
1092
+ }
1093
+
1094
+ # Once it's registered, you can't register another URL with that alias
1095
+ assert_raises(NamespaceAliasRegistrationError) {
1096
+ Message.register_namespace_alias('http://janrain.com/', alias_)
1097
+ }
1098
+
1099
+ # It gets used automatically by the Message class:
1100
+ msg = Message.from_openid_args({'invalid.stuff' => 'things'})
1101
+ assert(msg.is_openid1)
1102
+ assert_equal(alias_, msg.namespaces.get_alias(invalid_ns))
1103
+ assert_equal(invalid_ns, msg.namespaces.get_namespace_uri(alias_))
1104
+ end
1105
+
1106
+ def test_alias_defined_twice
1107
+ nsm = NamespaceMap.new
1108
+ uri = 'urn:bogus'
1109
+
1110
+ nsm.add_alias(uri, 'foos')
1111
+ assert_raises(IndexError) {
1112
+ nsm.add_alias(uri, 'ball')
1113
+ }
1114
+ end
1115
+ end
1116
+ end