atom-tools 0.9.1 → 0.9.2

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 (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