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