ratom-instructure 0.6.9
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +135 -0
- data/LICENSE +20 -0
- data/README.rdoc +293 -0
- data/Rakefile +59 -0
- data/VERSION.yml +5 -0
- data/lib/atom.rb +796 -0
- data/lib/atom/configuration.rb +24 -0
- data/lib/atom/pub.rb +251 -0
- data/lib/atom/version.rb +7 -0
- data/lib/atom/xml/parser.rb +413 -0
- data/ratom.gemspec +95 -0
- data/spec/app/member_entry.atom +31 -0
- data/spec/app/service.xml +36 -0
- data/spec/app/service_xml_base.xml +37 -0
- data/spec/atom/pub_spec.rb +517 -0
- data/spec/atom_spec.rb +1385 -0
- data/spec/conformance/baseuri.atom +19 -0
- data/spec/conformance/divtest.atom +32 -0
- data/spec/conformance/linktests.xml +103 -0
- data/spec/conformance/nondefaultnamespace-baseline.atom +25 -0
- data/spec/conformance/nondefaultnamespace-xhtml.atom +25 -0
- data/spec/conformance/nondefaultnamespace.atom +25 -0
- data/spec/conformance/ordertest.xml +112 -0
- data/spec/conformance/title/html-cdata.atom +22 -0
- data/spec/conformance/title/html-entity.atom +22 -0
- data/spec/conformance/title/html-ncr.atom +22 -0
- data/spec/conformance/title/text-cdata.atom +22 -0
- data/spec/conformance/title/text-entity.atom +21 -0
- data/spec/conformance/title/text-ncr.atom +21 -0
- data/spec/conformance/title/xhtml-entity.atom +21 -0
- data/spec/conformance/title/xhtml-ncr.atom +21 -0
- data/spec/conformance/unknown-namespace.atom +25 -0
- data/spec/conformance/xmlbase.atom +133 -0
- data/spec/fixtures/complex_single_entry.atom +45 -0
- data/spec/fixtures/created_entry.atom +31 -0
- data/spec/fixtures/entry.atom +30 -0
- data/spec/fixtures/entry_with_custom_extensions.atom +8 -0
- data/spec/fixtures/entry_with_simple_extensions.atom +31 -0
- data/spec/fixtures/entry_with_single_custom_extension.atom +6 -0
- data/spec/fixtures/multiple_entry.atom +0 -0
- data/spec/fixtures/simple_single_entry.atom +21 -0
- data/spec/fixtures/with_stylesheet.atom +8 -0
- data/spec/paging/first_paged_feed.atom +21 -0
- data/spec/paging/last_paged_feed.atom +21 -0
- data/spec/paging/middle_paged_feed.atom +22 -0
- data/spec/property.rb +31 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +46 -0
- metadata +147 -0
data/ratom.gemspec
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{ratom-instructure}
|
8
|
+
s.version = "0.6.9"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Peerworks", "Sean Geoghegan", "Jacob Fugal"]
|
12
|
+
s.date = %q{2011-07-13}
|
13
|
+
s.description = %q{A fast Atom Syndication and Publication API based on libxml}
|
14
|
+
s.email = %q{seangeo@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"History.txt",
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION.yml",
|
25
|
+
"lib/atom.rb",
|
26
|
+
"lib/atom/configuration.rb",
|
27
|
+
"lib/atom/pub.rb",
|
28
|
+
"lib/atom/version.rb",
|
29
|
+
"lib/atom/xml/parser.rb",
|
30
|
+
"ratom.gemspec",
|
31
|
+
"spec/app/member_entry.atom",
|
32
|
+
"spec/app/service.xml",
|
33
|
+
"spec/app/service_xml_base.xml",
|
34
|
+
"spec/atom/pub_spec.rb",
|
35
|
+
"spec/atom_spec.rb",
|
36
|
+
"spec/conformance/baseuri.atom",
|
37
|
+
"spec/conformance/divtest.atom",
|
38
|
+
"spec/conformance/linktests.xml",
|
39
|
+
"spec/conformance/nondefaultnamespace-baseline.atom",
|
40
|
+
"spec/conformance/nondefaultnamespace-xhtml.atom",
|
41
|
+
"spec/conformance/nondefaultnamespace.atom",
|
42
|
+
"spec/conformance/ordertest.xml",
|
43
|
+
"spec/conformance/title/html-cdata.atom",
|
44
|
+
"spec/conformance/title/html-entity.atom",
|
45
|
+
"spec/conformance/title/html-ncr.atom",
|
46
|
+
"spec/conformance/title/text-cdata.atom",
|
47
|
+
"spec/conformance/title/text-entity.atom",
|
48
|
+
"spec/conformance/title/text-ncr.atom",
|
49
|
+
"spec/conformance/title/xhtml-entity.atom",
|
50
|
+
"spec/conformance/title/xhtml-ncr.atom",
|
51
|
+
"spec/conformance/unknown-namespace.atom",
|
52
|
+
"spec/conformance/xmlbase.atom",
|
53
|
+
"spec/fixtures/complex_single_entry.atom",
|
54
|
+
"spec/fixtures/created_entry.atom",
|
55
|
+
"spec/fixtures/entry.atom",
|
56
|
+
"spec/fixtures/entry_with_custom_extensions.atom",
|
57
|
+
"spec/fixtures/entry_with_simple_extensions.atom",
|
58
|
+
"spec/fixtures/entry_with_single_custom_extension.atom",
|
59
|
+
"spec/fixtures/multiple_entry.atom",
|
60
|
+
"spec/fixtures/simple_single_entry.atom",
|
61
|
+
"spec/fixtures/with_stylesheet.atom",
|
62
|
+
"spec/paging/first_paged_feed.atom",
|
63
|
+
"spec/paging/last_paged_feed.atom",
|
64
|
+
"spec/paging/middle_paged_feed.atom",
|
65
|
+
"spec/property.rb",
|
66
|
+
"spec/spec.opts",
|
67
|
+
"spec/spec_helper.rb"
|
68
|
+
]
|
69
|
+
s.homepage = %q{http://github.com/lukfugl/ratom}
|
70
|
+
s.require_paths = ["lib"]
|
71
|
+
s.rubygems_version = %q{1.6.2}
|
72
|
+
s.summary = %q{Atom Syndication and Publication API}
|
73
|
+
s.test_files = [
|
74
|
+
"spec/atom/pub_spec.rb",
|
75
|
+
"spec/atom_spec.rb",
|
76
|
+
"spec/property.rb",
|
77
|
+
"spec/spec_helper.rb"
|
78
|
+
]
|
79
|
+
|
80
|
+
if s.respond_to? :specification_version then
|
81
|
+
s.specification_version = 3
|
82
|
+
|
83
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
84
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
85
|
+
s.add_runtime_dependency(%q<libxml-ruby>, [">= 1.1.2"])
|
86
|
+
else
|
87
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
88
|
+
s.add_dependency(%q<libxml-ruby>, [">= 1.1.2"])
|
89
|
+
end
|
90
|
+
else
|
91
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
92
|
+
s.add_dependency(%q<libxml-ruby>, [">= 1.1.2"])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<?xml version="1.0" ?>
|
2
|
+
<entry xmlns="http://www.w3.org/2005/Atom">
|
3
|
+
<title>Atom draft-07 snapshot</title>
|
4
|
+
<link rel="alternate" type="text/html"
|
5
|
+
href="http://example.org/2005/04/02/atom"/>
|
6
|
+
<link rel="edit" href="http://example.org/member_entry.atom"/>
|
7
|
+
<link rel="enclosure" type="audio/mpeg" length="1337"
|
8
|
+
href="http://example.org/audio/ph34r_my_podcast.mp3"/>
|
9
|
+
<id>tag:example.org,2003:3.2397</id>
|
10
|
+
<updated>2005-07-31T12:29:29Z</updated>
|
11
|
+
<published>2003-12-13T08:29:29-04:00</published>
|
12
|
+
<author>
|
13
|
+
<name>Mark Pilgrim</name>
|
14
|
+
<uri>http://example.org/</uri>
|
15
|
+
<email>f8dy@example.com</email>
|
16
|
+
</author>
|
17
|
+
<contributor>
|
18
|
+
<name>Sam Ruby</name>
|
19
|
+
</contributor>
|
20
|
+
<contributor>
|
21
|
+
<name>Joe Gregorio</name>
|
22
|
+
</contributor>
|
23
|
+
<content type="xhtml" xml:lang="en"
|
24
|
+
xml:base="http://diveintomark.org/">
|
25
|
+
<div xmlns="http://www.w3.org/1999/xhtml">
|
26
|
+
<p>
|
27
|
+
<i>[Update: The Atom draft is finished.]</i>
|
28
|
+
</p>
|
29
|
+
</div>
|
30
|
+
</content>
|
31
|
+
</entry>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<?xml version="1.0" encoding='utf-8'?>
|
2
|
+
<service xmlns="http://www.w3.org/2007/app"
|
3
|
+
xmlns:atom="http://www.w3.org/2005/Atom">
|
4
|
+
<workspace>
|
5
|
+
<atom:title>Main Site</atom:title>
|
6
|
+
<collection
|
7
|
+
href="http://example.org/blog/main" >
|
8
|
+
<atom:title>My Blog Entries</atom:title>
|
9
|
+
<categories
|
10
|
+
href="http://example.org/cats/forMain.cats" />
|
11
|
+
</collection>
|
12
|
+
<collection
|
13
|
+
href="http://example.org/blog/pic" >
|
14
|
+
<atom:title>Pictures</atom:title>
|
15
|
+
<accept>image/png</accept>
|
16
|
+
<accept>image/jpeg</accept>
|
17
|
+
<accept>image/gif</accept>
|
18
|
+
</collection>
|
19
|
+
</workspace>
|
20
|
+
<workspace>
|
21
|
+
<atom:title>Sidebar Blog</atom:title>
|
22
|
+
<collection
|
23
|
+
href="http://example.org/sidebar/list" >
|
24
|
+
<atom:title>Remaindered Links</atom:title>
|
25
|
+
<accept>application/atom+xml;type=entry</accept>
|
26
|
+
<categories fixed="yes">
|
27
|
+
<atom:category
|
28
|
+
scheme="http://example.org/extra-cats/"
|
29
|
+
term="joke" />
|
30
|
+
<atom:category
|
31
|
+
scheme="http://example.org/extra-cats/"
|
32
|
+
term="serious" />
|
33
|
+
</categories>
|
34
|
+
</collection>
|
35
|
+
</workspace>
|
36
|
+
</service>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<?xml version="1.0" encoding='utf-8'?>
|
2
|
+
<service xmlns="http://www.w3.org/2007/app"
|
3
|
+
xmlns:atom="http://www.w3.org/2005/Atom"
|
4
|
+
xml:base="http://example.org/">
|
5
|
+
<workspace>
|
6
|
+
<atom:title>Main Site</atom:title>
|
7
|
+
<collection
|
8
|
+
href="/blog/main" >
|
9
|
+
<atom:title>My Blog Entries</atom:title>
|
10
|
+
<categories
|
11
|
+
href="/cats/forMain.cats" />
|
12
|
+
</collection>
|
13
|
+
<collection
|
14
|
+
href="http://example.org/blog/pic" >
|
15
|
+
<atom:title>Pictures</atom:title>
|
16
|
+
<accept>image/png</accept>
|
17
|
+
<accept>image/jpeg</accept>
|
18
|
+
<accept>image/gif</accept>
|
19
|
+
</collection>
|
20
|
+
</workspace>
|
21
|
+
<workspace>
|
22
|
+
<atom:title>Sidebar Blog</atom:title>
|
23
|
+
<collection
|
24
|
+
href="http://example.org/sidebar/list" >
|
25
|
+
<atom:title>Remaindered Links</atom:title>
|
26
|
+
<accept>application/atom+xml;type=entry</accept>
|
27
|
+
<categories fixed="yes">
|
28
|
+
<atom:category
|
29
|
+
scheme="http://example.org/extra-cats/"
|
30
|
+
term="joke" />
|
31
|
+
<atom:category
|
32
|
+
scheme="http://example.org/extra-cats/"
|
33
|
+
term="serious" />
|
34
|
+
</categories>
|
35
|
+
</collection>
|
36
|
+
</workspace>
|
37
|
+
</service>
|
@@ -0,0 +1,517 @@
|
|
1
|
+
# Copyright (c) 2008 The Kaphan Foundation
|
2
|
+
#
|
3
|
+
# For licensing information see LICENSE.
|
4
|
+
#
|
5
|
+
# Please visit http://www.peerworks.org/contact for further information.
|
6
|
+
#
|
7
|
+
|
8
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
9
|
+
require 'atom'
|
10
|
+
require 'atom/pub'
|
11
|
+
require 'atom/version'
|
12
|
+
require 'uri'
|
13
|
+
require 'net/http'
|
14
|
+
|
15
|
+
shared_examples_for 'parser of spec/app/service.xml' do
|
16
|
+
it "should have 2 workspaces" do
|
17
|
+
@service.should have(2).workspaces
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have a title" do
|
21
|
+
@workspace.title.should == "Main Site"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should have 2 collections" do
|
25
|
+
@workspace.should have(2).collections
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have the right href" do
|
29
|
+
@collection1.href.should == 'http://example.org/blog/main'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have categories" do
|
33
|
+
@collection1.categories.should_not be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have a href on categories" do
|
37
|
+
@collection1.categories.href.should == "http://example.org/cats/forMain.cats"
|
38
|
+
@collection1.categories.fixed?.should be_false
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have a title" do
|
42
|
+
@collection1.title.should == 'My Blog Entries'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have a title" do
|
46
|
+
@collection2.title.should == 'Pictures'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have the right href" do
|
50
|
+
@collection2.href.should == 'http://example.org/blog/pic'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should not have categories" do
|
54
|
+
@collection2.categories.should be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should have 3 accepts" do
|
58
|
+
@collection2.should have(3).accepts
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should accept 'image/png'" do
|
62
|
+
@collection2.accepts.should include('image/png')
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should accept 'image/jpeg'" do
|
66
|
+
@collection2.accepts.should include('image/jpeg')
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should accept 'image/gif'" do
|
70
|
+
@collection2.accepts.should include('image/gif')
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should have a title on workspace 2" do
|
74
|
+
@workspace2.title.should == 'Sidebar Blog'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should have 1 collection on workspace 2" do
|
78
|
+
@workspace2.should have(1).collections
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should have a title on collection 3" do
|
82
|
+
@collection3.title.should == 'Remaindered Links'
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should have 1 accept on collection 3" do
|
86
|
+
@collection3.should have(1).accepts
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should accept 'application/atom+xml;type=entry'" do
|
90
|
+
@collection3.accepts.should include('application/atom+xml;type=entry')
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should have categories" do
|
94
|
+
@collection3.categories.should_not be_nil
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should have fixed == 'yes' on categories" do
|
98
|
+
@collection3.categories.fixed.should == "yes"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should have fixed? == true on categories" do
|
102
|
+
@collection3.categories.fixed?.should be_true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe Atom::Pub do
|
107
|
+
describe Atom::Pub::Service do
|
108
|
+
it "should load from a URL" do
|
109
|
+
uri = URI.parse('http://example.com/service.xml')
|
110
|
+
response = Net::HTTPSuccess.new(nil, nil, nil)
|
111
|
+
response.stub!(:body).and_return(File.read('spec/app/service.xml'))
|
112
|
+
mock_http_get(uri, response)
|
113
|
+
|
114
|
+
Atom::Pub::Service.load_service(uri).should be_an_instance_of(Atom::Pub::Service)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should raise ArgumentError with a non-http URL" do
|
118
|
+
lambda { Atom::Pub::Service.load_service(URI.parse('file:/tmp')) }.should raise_error(ArgumentError)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should be able to be created without xml" do
|
122
|
+
lambda { Atom::Pub::Service.new }.should_not raise_error
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should yield in the initializer" do
|
126
|
+
yielded = false
|
127
|
+
Atom::Pub::Service.new do
|
128
|
+
yielded = true
|
129
|
+
end
|
130
|
+
|
131
|
+
yielded.should be_true
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should parse it's output" do
|
135
|
+
orig = File.read('spec/app/service.xml')
|
136
|
+
svc = Atom::Pub::Service.load_service(orig)
|
137
|
+
xml = svc.to_xml
|
138
|
+
lambda do
|
139
|
+
Atom::Pub::Service.load_service(xml)
|
140
|
+
end.should_not raise_error
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "load_service" do
|
144
|
+
before(:all) do
|
145
|
+
@service = Atom::Pub::Service.load_service(File.open('spec/app/service.xml'))
|
146
|
+
@workspace = @service.workspaces.first
|
147
|
+
@workspace2 = @service.workspaces[1]
|
148
|
+
@collection1 = @workspace.collections.first
|
149
|
+
@collection2 = @workspace.collections[1]
|
150
|
+
@collection3 = @workspace2.collections.first
|
151
|
+
end
|
152
|
+
|
153
|
+
it_should_behave_like 'parser of spec/app/service.xml'
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "load service with xml:base" do
|
157
|
+
before(:all) do
|
158
|
+
@service = Atom::Pub::Service.load_service(File.open('spec/app/service_xml_base.xml'))
|
159
|
+
@workspace = @service.workspaces.first
|
160
|
+
@workspace2 = @service.workspaces[1]
|
161
|
+
@collection1 = @workspace.collections.first
|
162
|
+
@collection2 = @workspace.collections[1]
|
163
|
+
@collection3 = @workspace2.collections.first
|
164
|
+
end
|
165
|
+
|
166
|
+
it_should_behave_like 'parser of spec/app/service.xml'
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "load_service with authentication" do
|
170
|
+
it "should pass credentials to the server" do
|
171
|
+
uri = URI.parse('http://example.com/service.xml')
|
172
|
+
response = Net::HTTPSuccess.new(nil, nil, nil)
|
173
|
+
response.stub!(:body).and_return(File.read('spec/app/service.xml'))
|
174
|
+
mock_http_get(uri, response, 'user', 'pass')
|
175
|
+
Atom::Pub::Service.load_service(uri, :user => 'user', :pass => 'pass')
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should pass credentials on to the collections" do
|
179
|
+
uri = URI.parse('http://example.com/service.xml')
|
180
|
+
response = Net::HTTPSuccess.new(nil, nil, nil)
|
181
|
+
response.stub!(:body).and_return(File.read('spec/app/service.xml'))
|
182
|
+
mock_http_get(uri, response, 'user', 'pass')
|
183
|
+
pub = Atom::Pub::Service.load_service(uri, :user => 'user', :pass => 'pass')
|
184
|
+
|
185
|
+
uri2 = URI.parse('http://example.org/blog/main')
|
186
|
+
response2 = Net::HTTPSuccess.new(nil, nil, nil)
|
187
|
+
response2.stub!(:body).and_return(File.read('spec/fixtures/simple_single_entry.atom'))
|
188
|
+
mock_http_get(uri2, response2, 'user', 'pass')
|
189
|
+
pub.workspaces.first.collections.first.feed(:user => 'user', :pass => 'pass')
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "#to_xml" do
|
194
|
+
before(:each) do
|
195
|
+
@svc = Atom::Pub::Service.load_service(File.read('spec/app/service.xml'))
|
196
|
+
@xml = @svc.to_xml
|
197
|
+
@service = Atom::Pub::Service.load_service(@xml)
|
198
|
+
@workspace = @service.workspaces.first
|
199
|
+
@workspace2 = @service.workspaces[1]
|
200
|
+
@collection1 = @workspace.collections.first
|
201
|
+
@collection2 = @workspace.collections[1]
|
202
|
+
@collection3 = @workspace2.collections.first
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should put title in Atom namespace" do
|
206
|
+
@xml.should match(%r{atom:title})
|
207
|
+
end
|
208
|
+
|
209
|
+
it_should_behave_like 'parser of spec/app/service.xml'
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe Atom::Pub::Collection do
|
214
|
+
describe '.new' do
|
215
|
+
it "should set the href from the hash" do
|
216
|
+
collection = Atom::Pub::Collection.new(:href => 'http://example.org/blog')
|
217
|
+
collection.href.should == 'http://example.org/blog'
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should set the href from a block" do
|
221
|
+
collection = Atom::Pub::Collection.new do |c|
|
222
|
+
c.href = "http://example.org/blog"
|
223
|
+
end
|
224
|
+
collection.href.should == 'http://example.org/blog'
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should return the feed" do
|
229
|
+
collection = Atom::Pub::Collection.new(:href => 'http://example.org/blog')
|
230
|
+
response = Net::HTTPSuccess.new(nil, nil, nil)
|
231
|
+
response.stub!(:body).and_return(File.read('spec/fixtures/simple_single_entry.atom'))
|
232
|
+
mock_http_get(URI.parse(collection.href), response)
|
233
|
+
collection.feed.should be_an_instance_of(Atom::Feed)
|
234
|
+
end
|
235
|
+
|
236
|
+
describe '#publish' do
|
237
|
+
before(:each) do
|
238
|
+
@collection = Atom::Pub::Collection.new(:href => 'http://example.org/blog')
|
239
|
+
@request_headers = {'Accept' => 'application/atom+xml',
|
240
|
+
'Content-Type' => 'application/atom+xml;type=entry',
|
241
|
+
'User-Agent' => "rAtom #{Atom::VERSION::STRING}"
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should send a POST request when an entry is published" do
|
246
|
+
entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
|
247
|
+
|
248
|
+
response = mock_response(Net::HTTPCreated, entry.to_xml.to_s)
|
249
|
+
|
250
|
+
request = mock('request')
|
251
|
+
Net::HTTP::Post.should_receive(:new).with('/blog', @request_headers).and_return(request)
|
252
|
+
|
253
|
+
http = mock('http')
|
254
|
+
http.should_receive(:request).with(request, entry.to_xml.to_s).and_return(response)
|
255
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
256
|
+
|
257
|
+
created = @collection.publish(entry)
|
258
|
+
created.should == entry
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should send a POST with basic auth request when an entry is published" do
|
262
|
+
entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
|
263
|
+
|
264
|
+
response = mock_response(Net::HTTPCreated, entry.to_xml.to_s)
|
265
|
+
|
266
|
+
request = mock('request')
|
267
|
+
request.should_receive(:basic_auth).with('user', 'pass')
|
268
|
+
Net::HTTP::Post.should_receive(:new).with('/blog', @request_headers).and_return(request)
|
269
|
+
|
270
|
+
http = mock('http')
|
271
|
+
http.should_receive(:request).with(request, entry.to_xml.to_s).and_return(response)
|
272
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
273
|
+
|
274
|
+
created = @collection.publish(entry, :user => 'user', :pass => 'pass')
|
275
|
+
created.should == entry
|
276
|
+
end
|
277
|
+
|
278
|
+
if Atom::Configuration.auth_hmac_enabled?
|
279
|
+
it "should send a POST with hmac authentication when an entry is published" do
|
280
|
+
entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
|
281
|
+
|
282
|
+
response = mock_response(Net::HTTPCreated, entry.to_xml.to_s)
|
283
|
+
|
284
|
+
http = mock('http')
|
285
|
+
http.should_receive(:request) do |request, entry_xml|
|
286
|
+
request['Authorization'].should match(/^AuthHMAC access_id:[a-zA-Z0-9\/+]+=*/)
|
287
|
+
response
|
288
|
+
end
|
289
|
+
|
290
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
291
|
+
|
292
|
+
created = @collection.publish(entry, :hmac_access_id => 'access_id', :hmac_secret_key => 'secret')
|
293
|
+
created.should == entry
|
294
|
+
end
|
295
|
+
else
|
296
|
+
xit "should send a POST with hmac authentication when an entry is published"
|
297
|
+
end
|
298
|
+
|
299
|
+
it "should behave well when no content is returned" do
|
300
|
+
entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
|
301
|
+
|
302
|
+
response = mock_response(Net::HTTPCreated, " ")
|
303
|
+
|
304
|
+
request = mock('request')
|
305
|
+
Net::HTTP::Post.should_receive(:new).with('/blog', @request_headers).and_return(request)
|
306
|
+
|
307
|
+
http = mock('http')
|
308
|
+
http.should_receive(:request).with(request, entry.to_xml.to_s).and_return(response)
|
309
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
310
|
+
|
311
|
+
created = @collection.publish(entry)
|
312
|
+
created.should == entry
|
313
|
+
end
|
314
|
+
|
315
|
+
it "should raise error when response is not HTTPCreated" do
|
316
|
+
entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
|
317
|
+
response = mock_response(Net::HTTPPreconditionFailed, "")
|
318
|
+
|
319
|
+
request = mock('request')
|
320
|
+
Net::HTTP::Post.should_receive(:new).with('/blog', @request_headers).and_return(request)
|
321
|
+
|
322
|
+
http = mock('http')
|
323
|
+
http.should_receive(:request).with(request, entry.to_xml.to_s).and_return(response)
|
324
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
325
|
+
|
326
|
+
lambda { @collection.publish(entry) }.should raise_error(Atom::Pub::ProtocolError)
|
327
|
+
end
|
328
|
+
|
329
|
+
it "should copy Location into edit link of entry" do
|
330
|
+
entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
|
331
|
+
|
332
|
+
response = mock_response(Net::HTTPCreated, entry.to_xml.to_s, 'Location' => 'http://example.org/edit/entry1.atom')
|
333
|
+
|
334
|
+
request = mock('request')
|
335
|
+
Net::HTTP::Post.should_receive(:new).with('/blog', @request_headers).and_return(request)
|
336
|
+
|
337
|
+
http = mock('http')
|
338
|
+
http.should_receive(:request).with(request, entry.to_xml.to_s).and_return(response)
|
339
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
340
|
+
|
341
|
+
created = @collection.publish(entry)
|
342
|
+
created.edit_link.should_not be_nil
|
343
|
+
created.edit_link.href.should == 'http://example.org/edit/entry1.atom'
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should update the entry when response is different" do
|
347
|
+
entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
|
348
|
+
response = mock_response(Net::HTTPCreated, File.read('spec/fixtures/created_entry.atom'),
|
349
|
+
'Location' => 'http://example.org/edit/atom')
|
350
|
+
|
351
|
+
request = mock('request')
|
352
|
+
Net::HTTP::Post.should_receive(:new).with('/blog', @request_headers).and_return(request)
|
353
|
+
|
354
|
+
http = mock('http')
|
355
|
+
http.should_receive(:request).with(request, entry.to_xml.to_s).and_return(response)
|
356
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
357
|
+
|
358
|
+
created = @collection.publish(entry)
|
359
|
+
created.should == Atom::Entry.load_entry(File.open('spec/fixtures/created_entry.atom'))
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
describe Atom::Pub::Workspace do
|
365
|
+
it "should do the block initialization thing" do
|
366
|
+
workspace = Atom::Pub::Workspace.new do |w|
|
367
|
+
w.title = "Title"
|
368
|
+
end
|
369
|
+
|
370
|
+
workspace.title.should == "Title"
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should do the hash initialization thing" do
|
374
|
+
workspace = Atom::Pub::Workspace.new(:title => 'Title')
|
375
|
+
workspace.title.should == "Title"
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
describe Atom::Entry do
|
380
|
+
before(:each) do
|
381
|
+
@request_headers = {'Accept' => 'application/atom+xml',
|
382
|
+
'Content-Type' => 'application/atom+xml;type=entry',
|
383
|
+
'User-Agent' => "rAtom #{Atom::VERSION::STRING}"
|
384
|
+
}
|
385
|
+
end
|
386
|
+
|
387
|
+
it "should send a PUT to the edit link on save!" do
|
388
|
+
entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
|
389
|
+
response = mock_response(Net::HTTPSuccess, nil)
|
390
|
+
|
391
|
+
request = mock('request')
|
392
|
+
Net::HTTP::Put.should_receive(:new).with('/member_entry.atom', @request_headers).and_return(request)
|
393
|
+
|
394
|
+
http = mock('http')
|
395
|
+
http.should_receive(:request).with(request, entry.to_xml.to_s).and_return(response)
|
396
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
397
|
+
|
398
|
+
entry.save!
|
399
|
+
end
|
400
|
+
|
401
|
+
it "should send a PUT with auth to the edit link on save!" do
|
402
|
+
entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
|
403
|
+
response = mock_response(Net::HTTPSuccess, nil)
|
404
|
+
|
405
|
+
request = mock('request')
|
406
|
+
request.should_receive(:basic_auth).with('user', 'pass')
|
407
|
+
Net::HTTP::Put.should_receive(:new).with('/member_entry.atom', @request_headers).and_return(request)
|
408
|
+
|
409
|
+
http = mock('http')
|
410
|
+
http.should_receive(:request).with(request, entry.to_xml.to_s).and_return(response)
|
411
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
412
|
+
|
413
|
+
entry.save!(:user => 'user', :pass => 'pass')
|
414
|
+
end
|
415
|
+
|
416
|
+
if Atom::Configuration.auth_hmac_enabled?
|
417
|
+
it "should send a PUT with hmac auth to the edit link on save!" do
|
418
|
+
entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
|
419
|
+
response = mock_response(Net::HTTPSuccess, nil)
|
420
|
+
|
421
|
+
http = mock('http')
|
422
|
+
http.should_receive(:request) do |request, entry_xml|
|
423
|
+
request['Authorization'].should match(/^AuthHMAC access_id:[a-zA-Z0-9\/+]+=*$/)
|
424
|
+
response
|
425
|
+
end
|
426
|
+
|
427
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
428
|
+
|
429
|
+
entry.save!(:hmac_access_id => 'access_id', :hmac_secret_key => 'secret')
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
it "should send a DELETE to the edit link on delete!" do
|
434
|
+
entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
|
435
|
+
response = mock_response(Net::HTTPSuccess, nil)
|
436
|
+
|
437
|
+
request = mock('request')
|
438
|
+
Net::HTTP::Delete.should_receive(:new).with('/member_entry.atom', an_instance_of(Hash)).and_return(request)
|
439
|
+
|
440
|
+
http = mock('http')
|
441
|
+
http.should_receive(:request).with(request).and_return(response)
|
442
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
443
|
+
|
444
|
+
entry.destroy!
|
445
|
+
end
|
446
|
+
|
447
|
+
it "should send a DELETE with basic auth to the edit link on delete!" do
|
448
|
+
entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
|
449
|
+
response = mock_response(Net::HTTPSuccess, nil)
|
450
|
+
|
451
|
+
request = mock('request')
|
452
|
+
request.should_receive(:basic_auth).with('user', 'pass')
|
453
|
+
Net::HTTP::Delete.should_receive(:new).with('/member_entry.atom', an_instance_of(Hash)).and_return(request)
|
454
|
+
|
455
|
+
http = mock('http')
|
456
|
+
http.should_receive(:request).with(request).and_return(response)
|
457
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
458
|
+
|
459
|
+
entry.destroy!(:user => 'user', :pass => 'pass')
|
460
|
+
end
|
461
|
+
|
462
|
+
if Atom::Configuration.auth_hmac_enabled?
|
463
|
+
it "should send a DELETE with hmac auth to the edit link on delete!" do
|
464
|
+
entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
|
465
|
+
response = mock_response(Net::HTTPSuccess, nil)
|
466
|
+
|
467
|
+
http = mock('http')
|
468
|
+
http.should_receive(:request) do |request|
|
469
|
+
request['Authorization'].should match(/^AuthHMAC access_id:[a-zA-Z0-9\/+]+=*$/)
|
470
|
+
response
|
471
|
+
end
|
472
|
+
|
473
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
474
|
+
|
475
|
+
entry.destroy!(:hmac_access_id => 'access_id', :hmac_secret_key => 'secret')
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
it "should raise exception on save! without an edit link" do
|
480
|
+
entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
|
481
|
+
lambda { entry.save! }.should raise_error(Atom::Pub::NotSupported)
|
482
|
+
end
|
483
|
+
|
484
|
+
it "should raise exception on save failure" do
|
485
|
+
entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
|
486
|
+
response = mock_response(Net::HTTPClientError, nil)
|
487
|
+
|
488
|
+
request = mock('request')
|
489
|
+
Net::HTTP::Put.should_receive(:new).with('/member_entry.atom', @request_headers).and_return(request)
|
490
|
+
|
491
|
+
http = mock('http')
|
492
|
+
http.should_receive(:request).with(request, entry.to_xml.to_s).and_return(response)
|
493
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
494
|
+
|
495
|
+
lambda { entry.save! }.should raise_error(Atom::Pub::ProtocolError)
|
496
|
+
end
|
497
|
+
|
498
|
+
it "should raise exception on destroy! without an edit link" do
|
499
|
+
entry = Atom::Entry.load_entry(File.open('spec/fixtures/entry.atom'))
|
500
|
+
lambda { entry.destroy! }.should raise_error(Atom::Pub::NotSupported)
|
501
|
+
end
|
502
|
+
|
503
|
+
it "should raise exception on destroy failure" do
|
504
|
+
entry = Atom::Entry.load_entry(File.open('spec/app/member_entry.atom'))
|
505
|
+
response = mock_response(Net::HTTPClientError, nil)
|
506
|
+
|
507
|
+
request = mock('request')
|
508
|
+
Net::HTTP::Delete.should_receive(:new).with('/member_entry.atom', an_instance_of(Hash)).and_return(request)
|
509
|
+
|
510
|
+
http = mock('http')
|
511
|
+
http.should_receive(:request).with(request).and_return(response)
|
512
|
+
Net::HTTP.should_receive(:start).with('example.org', 80).and_yield(http)
|
513
|
+
|
514
|
+
lambda { entry.destroy! }.should raise_error(Atom::Pub::ProtocolError)
|
515
|
+
end
|
516
|
+
end
|
517
|
+
end
|