atom-tools 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/Rakefile +1 -1
  2. data/doc/classes/Atom/Author.html +130 -0
  3. data/doc/classes/Atom/Category.html +128 -0
  4. data/doc/classes/Atom/Collection.html +322 -0
  5. data/doc/classes/Atom/Content.html +129 -0
  6. data/doc/classes/Atom/Contributor.html +119 -0
  7. data/doc/classes/Atom/DigestAuth.html +285 -0
  8. data/doc/classes/Atom/Element.html +325 -0
  9. data/doc/classes/Atom/Entry.html +369 -0
  10. data/doc/classes/Atom/Feed.html +595 -0
  11. data/doc/classes/Atom/HTTP.html +436 -0
  12. data/doc/classes/Atom/HTTPResponse.html +149 -0
  13. data/doc/classes/Atom/Link.html +137 -0
  14. data/doc/classes/Atom/Service.html +260 -0
  15. data/doc/classes/Atom/Text.html +245 -0
  16. data/doc/classes/Atom/Workspace.html +121 -0
  17. data/doc/classes/XHTML.html +118 -0
  18. data/doc/created.rid +1 -0
  19. data/doc/files/README.html +213 -0
  20. data/doc/files/lib/atom/collection_rb.html +110 -0
  21. data/doc/files/lib/atom/element_rb.html +109 -0
  22. data/doc/files/lib/atom/entry_rb.html +111 -0
  23. data/doc/files/lib/atom/feed_rb.html +112 -0
  24. data/doc/files/lib/atom/http_rb.html +112 -0
  25. data/doc/files/lib/atom/service_rb.html +111 -0
  26. data/doc/files/lib/atom/text_rb.html +109 -0
  27. data/doc/files/lib/atom/xml_rb.html +110 -0
  28. data/doc/files/lib/atom/yaml_rb.html +109 -0
  29. data/doc/fr_class_index.html +42 -0
  30. data/doc/fr_file_index.html +36 -0
  31. data/doc/fr_method_index.html +69 -0
  32. data/doc/index.html +24 -0
  33. data/doc/rdoc-style.css +208 -0
  34. data/lib/atom/collection.rb +0 -21
  35. data/lib/atom/entry.rb +13 -0
  36. data/lib/atom/feed.rb +6 -7
  37. data/lib/atom/http.rb +97 -19
  38. data/lib/atom/service.rb +2 -22
  39. data/lib/atom/yaml.rb +1 -1
  40. data/test/test_feed.rb +27 -4
  41. data/test/test_http.rb +153 -34
  42. metadata +39 -2
@@ -9,8 +9,6 @@ module Atom
9
9
 
10
10
  class WrongNamespace < RuntimeError #:nodoc:
11
11
  end
12
- class WrongMimetype < RuntimeError # :nodoc:
13
- end
14
12
  class WrongResponse < RuntimeError # :nodoc:
15
13
  end
16
14
 
@@ -102,16 +100,13 @@ module Atom
102
100
 
103
101
  rxml = nil
104
102
 
105
- res = @http.get(base)
103
+ res = @http.get(base, "Accept" => "application/atomserv+xml")
104
+ res.validate_content_type(["application/atomserv+xml"])
106
105
 
107
106
  unless res.code == "200" # XXX needs to handle redirects, &c.
108
107
  raise WrongResponse, "service document URL responded with unexpected code #{res.code}"
109
108
  end
110
109
 
111
- unless res.content_type == "application/atomserv+xml"
112
- raise WrongMimetype, "this isn't an atom service document!"
113
- end
114
-
115
110
  parse(res.body, base)
116
111
  end
117
112
 
@@ -152,19 +147,4 @@ module Atom
152
147
  doc
153
148
  end
154
149
  end
155
-
156
- class Entry
157
- # the @href of an entry's link[@rel="edit"]
158
- def edit_url
159
- begin
160
- edit_link = self.links.find do |link|
161
- link["rel"] == "edit"
162
- end
163
-
164
- edit_link["href"]
165
- rescue
166
- nil
167
- end
168
- end
169
- end
170
150
  end
@@ -50,7 +50,7 @@ module Atom
50
50
  end
51
51
  end
52
52
  def to_yaml_style # :nodoc:
53
- if @content.match("\n")
53
+ if @content.to_s.match("\n")
54
54
  :fold
55
55
  else
56
56
  :plain
@@ -60,6 +60,8 @@ END
60
60
 
61
61
  def test_update
62
62
  @s.mount_proc("/") do |req,res|
63
+ assert_equal "application/atom+xml", req["Accept"]
64
+
63
65
  res.content_type = "application/atom+xml"
64
66
  res.body = @test_feed
65
67
 
@@ -89,6 +91,9 @@ END
89
91
 
90
92
  @s.stop
91
93
  end
94
+ # there's some kind of race condition here that will result in a
95
+ # timeout sometimes. this is a dirty fix.
96
+ sleep 0.5
92
97
  one_shot
93
98
  end
94
99
 
@@ -96,15 +101,32 @@ END
96
101
 
97
102
  # even if it looks like a feed, the server's word is law
98
103
  c.call("text/plain")
99
- assert_raise(Atom::HTTPException) { feed.update! }
104
+ assert_raise(Atom::WrongMimetype) { feed.update! }
105
+
106
+ # a parameter shouldn't change the type
107
+ c.call("application/atom+xml;type=feed")
108
+ assert_nothing_raised { feed.update! }
109
+
110
+ # type and subtype are case insensitive (param. attribute names too)
111
+ c.call("ApPliCatIon/ATOM+XML")
112
+ assert_nothing_raised { feed.update! }
100
113
 
101
114
  # text/xml isn't the preferred mimetype, but we'll accept it
102
115
  c.call("text/xml")
103
116
  assert_nothing_raised { feed.update! }
104
117
 
105
118
  # same goes for application/xml
106
- # XXX c.call("application/xml")
107
- # assert_nothing_raised { feed.update! }
119
+ c.call("application/xml")
120
+ assert_nothing_raised { feed.update! }
121
+
122
+ # nil content type
123
+ @s.mount_proc("/") do |req,res|
124
+ res.body = @test_feed
125
+
126
+ @s.stop
127
+ end
128
+ one_shot
129
+ assert_raises(Atom::HTTPException) { feed.update! }
108
130
  end
109
131
 
110
132
  def test_conditional_get
@@ -139,7 +161,8 @@ END
139
161
  assert_equal 'Wed, 15 Nov 1995 04:58:08 GMT', req["If-Modified-Since"]
140
162
 
141
163
  res.status = 304
142
- res.body = "this hasn't been modified"
164
+ res.content_type = "application/atom+xml"
165
+ res.body = @test_feed
143
166
 
144
167
  @s.stop
145
168
  end
@@ -3,10 +3,14 @@ require "test/unit"
3
3
  require "atom/http"
4
4
  require "webrick"
5
5
 
6
- class AtomProtocolTest < Test::Unit::TestCase
6
+ class AtomHTTPTest < Test::Unit::TestCase
7
7
  REALM = "test authentication"
8
8
  USER = "test_user"
9
9
  PASS = "aoeuaoeu"
10
+
11
+ # for Google AuthSub authentication
12
+ TOKEN = "pq7266382__838"
13
+
10
14
  SECRET_DATA = "I kissed a boy once"
11
15
 
12
16
  def setup
@@ -18,11 +22,13 @@ class AtomProtocolTest < Test::Unit::TestCase
18
22
  end
19
23
 
20
24
  def test_parse_wwwauth
25
+ # a Basic WWW-Authenticate
21
26
  header = 'realm="SokEvo"'
22
27
 
23
28
  params = @http.send :parse_quoted_wwwauth, header
24
29
  assert_equal "SokEvo", params[:realm]
25
30
 
31
+ # Digest is parsed a bit differently
26
32
  header = 'opaque="07UrfUiCYac5BbWJ", algorithm=MD5-sess, qop="auth", stale=TRUE, nonce="MDAx0Mzk", realm="test authentication"'
27
33
 
28
34
  params = @http.send :parse_wwwauth_digest, header
@@ -36,57 +42,120 @@ class AtomProtocolTest < Test::Unit::TestCase
36
42
  end
37
43
 
38
44
  def test_GET
39
- @s.mount_proc("/") do |req,res|
45
+ mount_one_shot do |req,res|
40
46
  assert_equal("/", req.path)
41
47
 
42
48
  res.content_type = "text/plain"
43
- res.body = "just junk"
44
-
45
- @s.stop
49
+ res.body = "Success!"
46
50
  end
47
51
 
48
- one_shot
49
-
50
52
  get_root
51
53
 
52
- assert_equal("200", @res.code)
53
- assert_equal("text/plain", @res.content_type)
54
- assert_equal("just junk", @res.body)
54
+ assert_equal "200", @res.code
55
+ assert_equal "text/plain", @res.content_type
56
+ assert_equal "Success!", @res.body
55
57
  end
56
58
 
57
59
  def test_GET_headers
58
- @s.mount_proc("/") do |req,res|
60
+ mount_one_shot do |req,res|
59
61
  assert_equal("tester agent", req["User-Agent"])
62
+ end
63
+
64
+ get_root("User-Agent" => "tester agent")
65
+
66
+ assert_equal "200", @res.code
67
+ end
68
+
69
+ def test_redirect
70
+ @s.mount_proc("/") do |req,res|
71
+ res.status = 302
72
+ res["Location"] = "http://localhost:#{@port}/redirected"
60
73
 
74
+ res.body = "ignore me."
75
+ end
76
+
77
+ @s.mount_proc("/redirected") do |req,res|
78
+ res.content_type = "text/plain"
79
+ res.body = "Success!"
80
+
61
81
  @s.stop
62
82
  end
63
83
 
84
+ one_shot; get_root
85
+
86
+ # the redirect should be transparent (to whatever extent it can be)
87
+ assert_equal "200", @res.code
88
+ assert_equal "Success!", @res.body
89
+ end
90
+
91
+ def test_redirect_loop
92
+ @s.mount_proc("/") do |req,res|
93
+ res.status = 302
94
+ res["Location"] = "http://localhost:#{@port}/redirected"
95
+ end
96
+
97
+ @s.mount_proc("/redirected") do |req,res|
98
+ res.status = 302
99
+ res["Location"] = "http://localhost:#{@port}/"
100
+ end
101
+
64
102
  one_shot
103
+
104
+ assert_raises(Atom::HTTPException) { get_root }
65
105
 
66
- get_root("User-Agent" => "tester agent")
106
+ @s.stop
107
+ end
108
+
109
+ def test_redirect_non_GET_non_HEAD
110
+ @s.mount_proc("/") do |req,res|
111
+ assert_equal "POST", req.request_method
112
+ res.status = 302
113
+ res["Location"] = "http://localhost:#{@port}/redirected"
114
+ end
115
+
116
+ @s.mount_proc("/redirected") do |req,res|
117
+ assert_equal "POST", req.request_method
118
+ assert_equal "important message", req.body
119
+ res.content_type = "text/plain"
120
+ res.body = "Success!"
121
+ end
122
+
123
+ one_shot
124
+
125
+ @res = @http.post "http://localhost:#{@port}/", "important message"
126
+
127
+ assert_equal "302", @res.code
67
128
 
68
- assert_equal("200", @res.code)
129
+ @http.allow_all_redirects = true
130
+
131
+ one_shot
132
+
133
+ @res = @http.post "http://localhost:#{@port}/", "important message"
134
+
135
+ assert_equal "200", @res.code
136
+ assert_equal "Success!", @res.body
137
+
138
+ @s.stop
69
139
  end
70
140
 
71
141
  def test_basic_auth
72
- @s.mount_proc("/") do |req,res|
142
+ mount_one_shot do |req,res|
73
143
  WEBrick::HTTPAuth.basic_auth(req, res, REALM) do |u,p|
74
144
  u == USER and p == PASS
75
145
  end
76
146
 
77
147
  res.body = SECRET_DATA
78
- @s.stop
79
148
  end
80
149
 
81
- one_shot
82
-
83
- # with no credentials
150
+ # no credentials
84
151
  assert_raises(Atom::Unauthorized) { get_root }
85
152
 
86
153
  @http.user = USER
87
154
  @http.pass = "incorrect_password"
88
155
 
89
- # with incorrect credentials
156
+ one_shot
157
+
158
+ # incorrect credentials
90
159
  assert_raises(Atom::Unauthorized) { get_root }
91
160
 
92
161
  @http.when_auth do |abs_url,realm|
@@ -95,19 +164,20 @@ class AtomProtocolTest < Test::Unit::TestCase
95
164
 
96
165
  [USER, PASS]
97
166
  end
98
-
167
+
99
168
  one_shot
100
-
101
- get_root
102
- assert_equal "200", @res.code
103
- assert_equal SECRET_DATA, @res.body
169
+
170
+ # correct credentials
171
+ assert_authenticates
104
172
  end
105
173
 
106
174
  def test_digest_auth
107
- # a dummy userdb
175
+ # a dummy userdb (saves me creating a file)
108
176
  userdb = {}
177
+ # with a single entry
109
178
  userdb[USER] = PASS
110
179
 
180
+ # HTTPAuth::DigestAuth#authenticate uses this
111
181
  def userdb.get_passwd(realm, user, reload)
112
182
  Digest::MD5::hexdigest([user, realm, self[user]].join(":"))
113
183
  end
@@ -132,14 +202,13 @@ class AtomProtocolTest < Test::Unit::TestCase
132
202
  @http.pass = PASS
133
203
 
134
204
  # correct credentials
135
- res = get_root
136
- assert_equal SECRET_DATA, res.body
205
+ assert_authenticates
137
206
 
138
207
  @s.stop
139
208
  end
140
209
 
141
210
  def test_wsse_auth
142
- @s.mount_proc("/") do |req,res|
211
+ mount_one_shot do |req,res|
143
212
  assert_equal 'WSSE profile="UsernameToken"', req["Authorization"]
144
213
 
145
214
  xwsse = req["X-WSSE"]
@@ -159,24 +228,74 @@ class AtomProtocolTest < Test::Unit::TestCase
159
228
  assert_equal password_digest, p[:PasswordDigest]
160
229
 
161
230
  res.body = SECRET_DATA
162
- @s.stop
163
231
  end
164
232
 
165
- one_shot
166
-
167
233
  @http.always_auth = :wsse
168
234
  @http.user = USER
169
235
  @http.pass = PASS
170
-
171
- get_root
172
236
 
237
+ assert_authenticates
238
+ end
239
+
240
+ def test_authsub_auth
241
+ mount_one_shot do |req,res|
242
+ assert_equal %{AuthSub token="#{TOKEN}"}, req["Authorization"]
243
+
244
+ res.body = SECRET_DATA
245
+ end
246
+
247
+ @http.always_auth = :authsub
248
+ @http.token = TOKEN
249
+
250
+ assert_authenticates
251
+ end
252
+
253
+ def test_https
254
+ require 'webrick/https'
255
+
256
+ @s = WEBrick::HTTPServer.new(
257
+ :Port => (@port + 1),
258
+ :DocumentRoot => Dir::pwd + "/htdocs",
259
+ :Logger => WEBrick::Log.new($stderr, WEBrick::Log::FATAL),
260
+ :AccessLog => [],
261
+ :SSLEnable => true,
262
+ :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
263
+ :SSLCertName => [ ["C","CA"], ["O","localhost"], ["CN", "WWW"] ]
264
+ )
265
+
266
+ mount_one_shot do |req,res|
267
+ res.body = SECRET_DATA
268
+ end
269
+
270
+ res = @http.get("https://localhost:#{@port + 1}/")
271
+
272
+ assert_equal "200", res.code
273
+ assert_equal SECRET_DATA, res.body
274
+ end
275
+
276
+ # mount a block on the test server, shutting the server down after a
277
+ # single request
278
+ def mount_one_shot &block
279
+ @s.mount_proc("/") do |req,res|
280
+ block.call req, res
281
+ @s.stop
282
+ end
283
+
284
+ one_shot
285
+ end
286
+
287
+ # test that we authenticated properly
288
+ def assert_authenticates
289
+ get_root
173
290
  assert_equal "200", @res.code
174
- assert_equal SECRET_DATA, @res.body
291
+ assert_equal SECRET_DATA, @res.body
175
292
  end
176
293
 
294
+ # performs a GET on the test server
177
295
  def get_root(*args)
178
296
  @res = @http.get("http://localhost:#{@port}/", *args)
179
297
  end
180
298
 
299
+ # sets up the server for a single request
181
300
  def one_shot; Thread.new { @s.start }; end
182
301
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: atom-tools
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.9.1
7
- date: 2006-11-26 00:00:00 -07:00
6
+ version: 0.9.2
7
+ date: 2006-12-27 00:00:00 -07:00
8
8
  summary: Tools for working with Atom Entries, Feeds and Collections
9
9
  require_paths:
10
10
  - lib
@@ -33,6 +33,43 @@ files:
33
33
  - Rakefile
34
34
  - setup.rb
35
35
  - bin/atom-client.rb
36
+ - doc/files
37
+ - doc/index.html
38
+ - doc/rdoc-style.css
39
+ - doc/fr_method_index.html
40
+ - doc/fr_class_index.html
41
+ - doc/fr_file_index.html
42
+ - doc/created.rid
43
+ - doc/classes
44
+ - doc/files/lib
45
+ - doc/files/README.html
46
+ - doc/files/lib/atom
47
+ - doc/files/lib/atom/feed_rb.html
48
+ - doc/files/lib/atom/text_rb.html
49
+ - doc/files/lib/atom/xml_rb.html
50
+ - doc/files/lib/atom/yaml_rb.html
51
+ - doc/files/lib/atom/service_rb.html
52
+ - doc/files/lib/atom/element_rb.html
53
+ - doc/files/lib/atom/entry_rb.html
54
+ - doc/files/lib/atom/http_rb.html
55
+ - doc/files/lib/atom/collection_rb.html
56
+ - doc/classes/Atom
57
+ - doc/classes/XHTML.html
58
+ - doc/classes/Atom/Service.html
59
+ - doc/classes/Atom/Author.html
60
+ - doc/classes/Atom/Element.html
61
+ - doc/classes/Atom/Feed.html
62
+ - doc/classes/Atom/DigestAuth.html
63
+ - doc/classes/Atom/Text.html
64
+ - doc/classes/Atom/Contributor.html
65
+ - doc/classes/Atom/HTTPResponse.html
66
+ - doc/classes/Atom/HTTP.html
67
+ - doc/classes/Atom/Link.html
68
+ - doc/classes/Atom/Collection.html
69
+ - doc/classes/Atom/Content.html
70
+ - doc/classes/Atom/Category.html
71
+ - doc/classes/Atom/Workspace.html
72
+ - doc/classes/Atom/Entry.html
36
73
  - test/test_constructs.rb
37
74
  - test/runtests.rb
38
75
  - test/test_feed.rb