feedzirra 0.7.1 → 0.8.0

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile +0 -14
  4. data/README.md +2 -241
  5. data/feedzirra.gemspec +2 -8
  6. data/lib/feedzirra.rb +2 -15
  7. data/lib/feedzirra/version.rb +1 -1
  8. metadata +7 -182
  9. data/.rspec +0 -1
  10. data/.travis.yml +0 -8
  11. data/Guardfile +0 -5
  12. data/Rakefile +0 -6
  13. data/benchmarks/README.md +0 -90
  14. data/benchmarks/basic.rb +0 -31
  15. data/benchmarks/feed_list.txt +0 -10
  16. data/benchmarks/feed_xml/apple.xml +0 -149
  17. data/benchmarks/feed_xml/cnn.xml +0 -278
  18. data/benchmarks/feed_xml/daring_fireball.xml +0 -1697
  19. data/benchmarks/feed_xml/engadget.xml +0 -604
  20. data/benchmarks/feed_xml/feedzirra_commits.xml +0 -370
  21. data/benchmarks/feed_xml/gizmodo.xml +0 -2
  22. data/benchmarks/feed_xml/loop.xml +0 -441
  23. data/benchmarks/feed_xml/rails.xml +0 -1938
  24. data/benchmarks/feed_xml/white_house.xml +0 -951
  25. data/benchmarks/feed_xml/xkcd.xml +0 -2
  26. data/benchmarks/fetching_systems.rb +0 -23
  27. data/benchmarks/other_libraries.rb +0 -73
  28. data/lib/feedzirra/core_ext.rb +0 -3
  29. data/lib/feedzirra/core_ext/date.rb +0 -19
  30. data/lib/feedzirra/core_ext/string.rb +0 -9
  31. data/lib/feedzirra/core_ext/time.rb +0 -31
  32. data/lib/feedzirra/feed.rb +0 -459
  33. data/lib/feedzirra/feed_entry_utilities.rb +0 -66
  34. data/lib/feedzirra/feed_utilities.rb +0 -103
  35. data/lib/feedzirra/parser.rb +0 -20
  36. data/lib/feedzirra/parser/atom.rb +0 -61
  37. data/lib/feedzirra/parser/atom_entry.rb +0 -34
  38. data/lib/feedzirra/parser/atom_feed_burner.rb +0 -22
  39. data/lib/feedzirra/parser/atom_feed_burner_entry.rb +0 -35
  40. data/lib/feedzirra/parser/google_docs_atom.rb +0 -28
  41. data/lib/feedzirra/parser/google_docs_atom_entry.rb +0 -29
  42. data/lib/feedzirra/parser/itunes_rss.rb +0 -50
  43. data/lib/feedzirra/parser/itunes_rss_item.rb +0 -41
  44. data/lib/feedzirra/parser/itunes_rss_owner.rb +0 -12
  45. data/lib/feedzirra/parser/rss.rb +0 -24
  46. data/lib/feedzirra/parser/rss_entry.rb +0 -37
  47. data/lib/feedzirra/parser/rss_feed_burner.rb +0 -23
  48. data/lib/feedzirra/parser/rss_feed_burner_entry.rb +0 -43
  49. data/spec/feedzirra/feed_entry_utilities_spec.rb +0 -62
  50. data/spec/feedzirra/feed_spec.rb +0 -762
  51. data/spec/feedzirra/feed_utilities_spec.rb +0 -273
  52. data/spec/feedzirra/parser/atom_entry_spec.rb +0 -86
  53. data/spec/feedzirra/parser/atom_feed_burner_entry_spec.rb +0 -47
  54. data/spec/feedzirra/parser/atom_feed_burner_spec.rb +0 -56
  55. data/spec/feedzirra/parser/atom_spec.rb +0 -76
  56. data/spec/feedzirra/parser/google_docs_atom_entry_spec.rb +0 -22
  57. data/spec/feedzirra/parser/google_docs_atom_spec.rb +0 -31
  58. data/spec/feedzirra/parser/itunes_rss_item_spec.rb +0 -63
  59. data/spec/feedzirra/parser/itunes_rss_owner_spec.rb +0 -18
  60. data/spec/feedzirra/parser/itunes_rss_spec.rb +0 -58
  61. data/spec/feedzirra/parser/rss_entry_spec.rb +0 -85
  62. data/spec/feedzirra/parser/rss_feed_burner_entry_spec.rb +0 -85
  63. data/spec/feedzirra/parser/rss_feed_burner_spec.rb +0 -57
  64. data/spec/feedzirra/parser/rss_spec.rb +0 -57
  65. data/spec/sample_feeds/AmazonWebServicesBlog.xml +0 -797
  66. data/spec/sample_feeds/AmazonWebServicesBlogFirstEntryContent.xml +0 -63
  67. data/spec/sample_feeds/AtomFeedWithSpacesAroundEquals.xml +0 -61
  68. data/spec/sample_feeds/FeedBurnerUrlNoAlternate.xml +0 -28
  69. data/spec/sample_feeds/GoogleDocsList.xml +0 -188
  70. data/spec/sample_feeds/HREFConsideredHarmful.xml +0 -314
  71. data/spec/sample_feeds/HREFConsideredHarmfulFirstEntry.xml +0 -22
  72. data/spec/sample_feeds/ITunesWithSpacesInAttributes.xml +0 -63
  73. data/spec/sample_feeds/PaulDixExplainsNothing.xml +0 -175
  74. data/spec/sample_feeds/PaulDixExplainsNothingAlternate.xml +0 -175
  75. data/spec/sample_feeds/PaulDixExplainsNothingFirstEntryContent.xml +0 -19
  76. data/spec/sample_feeds/PaulDixExplainsNothingWFW.xml +0 -174
  77. data/spec/sample_feeds/SamRuby.xml +0 -583
  78. data/spec/sample_feeds/TechCrunch.xml +0 -1515
  79. data/spec/sample_feeds/TechCrunchFirstEntry.xml +0 -9
  80. data/spec/sample_feeds/TechCrunchFirstEntryDescription.xml +0 -3
  81. data/spec/sample_feeds/TenderLovemaking.xml +0 -516
  82. data/spec/sample_feeds/TenderLovemakingFirstEntry.xml +0 -66
  83. data/spec/sample_feeds/TrotterCashionHome.xml +0 -611
  84. data/spec/sample_feeds/TypePadNews.xml +0 -368
  85. data/spec/sample_feeds/atom_with_link_tag_for_url_unmarked.xml +0 -31
  86. data/spec/sample_feeds/itunes.xml +0 -67
  87. data/spec/sample_feeds/pet_atom.xml +0 -497
  88. data/spec/spec_helper.rb +0 -88
@@ -1,41 +0,0 @@
1
- module Feedzirra
2
-
3
- module Parser
4
- # iTunes extensions to the standard RSS2.0 item
5
- # Source: http://www.apple.com/itunes/whatson/podcasts/specs.html
6
- class ITunesRSSItem
7
- include SAXMachine
8
- include FeedEntryUtilities
9
-
10
- element :author
11
- element :guid, :as => :entry_id
12
- element :title
13
- element :link, :as => :url
14
- element :description, :as => :summary
15
- element :"content:encoded", :as => :content
16
- element :pubDate, :as => :published
17
-
18
- # If author is not present use author tag on the item
19
- element :"itunes:author", :as => :itunes_author
20
- element :"itunes:block", :as => :itunes_block
21
- element :"itunes:duration", :as => :itunes_duration
22
- element :"itunes:explicit", :as => :itunes_explicit
23
- element :"itunes:keywords", :as => :itunes_keywords
24
- element :"itunes:subtitle", :as => :itunes_subtitle
25
- element :"itunes:image", :value => :href, :as => :itunes_image
26
- element :"itunes:isClosedCaptioned", :as => :itunes_closed_captioned
27
- element :"itunes:order", :as => :itunes_order
28
- # If summary is not present, use the description tag
29
- element :"itunes:summary", :as => :itunes_summary
30
- element :enclosure, :value => :length, :as => :enclosure_length
31
- element :enclosure, :value => :type, :as => :enclosure_type
32
- element :enclosure, :value => :url, :as => :enclosure_url
33
-
34
- def guid
35
- warn "Feedzirra: ITunesRSSItem.guid is deprecated, please use `id` or `entry_id` instead. This will be removed in version 1.0"
36
- id
37
- end
38
- end
39
- end
40
-
41
- end
@@ -1,12 +0,0 @@
1
- module Feedzirra
2
-
3
- module Parser
4
- class ITunesRSSOwner
5
- include SAXMachine
6
- include FeedUtilities
7
- element :"itunes:name", :as => :name
8
- element :"itunes:email", :as => :email
9
- end
10
- end
11
-
12
- end
@@ -1,24 +0,0 @@
1
- module Feedzirra
2
-
3
- module Parser
4
- # Parser for dealing with RSS feeds.
5
- class RSS
6
- include SAXMachine
7
- include FeedUtilities
8
- element :rss, as: :version, value: :version
9
- element :title
10
- element :description
11
- element :link, :as => :url
12
- elements :item, :as => :entries, :class => RSSEntry
13
-
14
- attr_accessor :feed_url
15
- attr_accessor :hubs
16
-
17
- def self.able_to_parse?(xml) #:nodoc:
18
- (/\<rss|\<rdf/ =~ xml) && !(/feedburner/ =~ xml)
19
- end
20
- end
21
-
22
- end
23
-
24
- end
@@ -1,37 +0,0 @@
1
- module Feedzirra
2
-
3
- module Parser
4
- # Parser for dealing with RDF feed entries.
5
- class RSSEntry
6
- include SAXMachine
7
- include FeedEntryUtilities
8
-
9
- element :title
10
- element :link, :as => :url
11
-
12
- element :"dc:creator", :as => :author
13
- element :author, :as => :author
14
- element :"content:encoded", :as => :content
15
- element :description, :as => :summary
16
-
17
- element :"media:content", :as => :image, :value => :url
18
- element :enclosure, :as => :image, :value => :url
19
-
20
- element :pubDate, :as => :published
21
- element :pubdate, :as => :published
22
- element :"dc:date", :as => :published
23
- element :"dc:Date", :as => :published
24
- element :"dcterms:created", :as => :published
25
-
26
-
27
- element :"dcterms:modified", :as => :updated
28
- element :issued, :as => :published
29
- elements :category, :as => :categories
30
-
31
- element :guid, :as => :entry_id
32
- element :"dc:identifier", :as => :entry_id
33
- end
34
-
35
- end
36
-
37
- end
@@ -1,23 +0,0 @@
1
- module Feedzirra
2
-
3
- module Parser
4
- # Parser for dealing with RSS feeds.
5
- class RSSFeedBurner
6
- include SAXMachine
7
- include FeedUtilities
8
- element :title
9
- element :description
10
- element :link, :as => :url
11
- elements :"atom10:link", :as => :hubs, :value => :href, :with => {:rel => "hub"}
12
- elements :item, :as => :entries, :class => RSSFeedBurnerEntry
13
-
14
- attr_accessor :feed_url
15
-
16
- def self.able_to_parse?(xml) #:nodoc:
17
- (/\<rss|\<rdf/ =~ xml) && (/feedburner/ =~ xml)
18
- end
19
- end
20
-
21
- end
22
-
23
- end
@@ -1,43 +0,0 @@
1
- module Feedzirra
2
-
3
- module Parser
4
- # Parser for dealing with RDF feed entries.
5
- class RSSFeedBurnerEntry
6
- include SAXMachine
7
- include FeedEntryUtilities
8
-
9
- element :title
10
-
11
- element :"feedburner:origLink", :as => :url
12
- element :link, :as => :url
13
-
14
- element :"dc:creator", :as => :author
15
- element :author, :as => :author
16
- element :"content:encoded", :as => :content
17
- element :description, :as => :summary
18
-
19
- element :"media:content", :as => :image, :value => :url
20
- element :enclosure, :as => :image, :value => :url
21
-
22
- element :pubDate, :as => :published
23
- element :pubdate, :as => :published
24
- element :"dc:date", :as => :published
25
- element :"dc:Date", :as => :published
26
- element :"dcterms:created", :as => :published
27
-
28
-
29
- element :"dcterms:modified", :as => :updated
30
- element :issued, :as => :published
31
- elements :category, :as => :categories
32
-
33
- element :guid, :as => :entry_id
34
-
35
- def url
36
- @url || @link
37
- end
38
-
39
- end
40
-
41
- end
42
-
43
- end
@@ -1,62 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Feedzirra::FeedUtilities do
4
- before(:each) do
5
- @klass = Class.new do
6
- include Feedzirra::FeedEntryUtilities
7
- end
8
- end
9
-
10
- describe "handling dates" do
11
- it "should parse an ISO 8601 formatted datetime into Time" do
12
- time = @klass.new.parse_datetime("2008-02-20T8:05:00-010:00")
13
- time.class.should == Time
14
- time.should == Time.parse_safely("Wed Feb 20 18:05:00 UTC 2008")
15
- end
16
-
17
- it "should parse a ISO 8601 with milliseconds into Time" do
18
- time = @klass.new.parse_datetime("2013-09-17T08:20:13.931-04:00")
19
- time.class.should == Time
20
- time.should == Time.parse_safely("Tue Sep 17 12:20:13 UTC 2013")
21
- end
22
- end
23
-
24
- describe "sanitizing" do
25
- before(:each) do
26
- @feed = Feedzirra::Feed.parse(sample_atom_feed)
27
- @entry = @feed.entries.first
28
- end
29
-
30
- it "doesn't fail when no elements are defined on includer" do
31
- expect { @klass.new.sanitize! }.to_not raise_error
32
- end
33
-
34
- it "should provide a sanitized title" do
35
- new_title = "<script>this is not safe</script>" + @entry.title
36
- @entry.title = new_title
37
- @entry.title.sanitize.should == Loofah.scrub_fragment(new_title, :prune).to_s
38
- end
39
-
40
- it "should sanitize content in place" do
41
- new_content = "<script>" + @entry.content
42
- @entry.content = new_content.dup
43
- @entry.content.sanitize!.should == Loofah.scrub_fragment(new_content, :prune).to_s
44
- @entry.content.should == Loofah.scrub_fragment(new_content, :prune).to_s
45
- end
46
-
47
- it "should sanitize things in place" do
48
- @entry.title += "<script>"
49
- @entry.author += "<script>"
50
- @entry.content += "<script>"
51
-
52
- cleaned_title = Loofah.scrub_fragment(@entry.title, :prune).to_s
53
- cleaned_author = Loofah.scrub_fragment(@entry.author, :prune).to_s
54
- cleaned_content = Loofah.scrub_fragment(@entry.content, :prune).to_s
55
-
56
- @entry.sanitize!
57
- @entry.title.should == cleaned_title
58
- @entry.author.should == cleaned_author
59
- @entry.content.should == cleaned_content
60
- end
61
- end
62
- end
@@ -1,762 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
-
3
- class Hell < StandardError; end
4
-
5
- class FailParser
6
- def self.parse(_, &on_failure)
7
- on_failure.call 'this parser always fails.'
8
- end
9
- end
10
-
11
- describe Feedzirra::Feed do
12
-
13
- describe "#add_common_feed_element" do
14
- before(:all) do
15
- Feedzirra::Feed.add_common_feed_element("generator")
16
- end
17
-
18
- it "should parse the added element out of Atom feeds" do
19
- Feedzirra::Feed.parse(sample_wfw_feed).generator.should == "TypePad"
20
- end
21
-
22
- it "should parse the added element out of Atom Feedburner feeds" do
23
- Feedzirra::Parser::Atom.new.should respond_to(:generator)
24
- end
25
-
26
- it "should parse the added element out of RSS feeds" do
27
- Feedzirra::Parser::RSS.new.should respond_to(:generator)
28
- end
29
- end
30
-
31
- describe "#add_common_feed_entry_element" do
32
- before(:all) do
33
- Feedzirra::Feed.add_common_feed_entry_element("wfw:commentRss", :as => :comment_rss)
34
- end
35
-
36
- it "should parse the added element out of Atom feeds entries" do
37
- Feedzirra::Feed.parse(sample_wfw_feed).entries.first.comment_rss.should == "this is the new val"
38
- end
39
-
40
- it "should parse the added element out of Atom Feedburner feeds entries" do
41
- Feedzirra::Parser::AtomEntry.new.should respond_to(:comment_rss)
42
- end
43
-
44
- it "should parse the added element out of RSS feeds entries" do
45
- Feedzirra::Parser::RSSEntry.new.should respond_to(:comment_rss)
46
- end
47
- end
48
-
49
- describe '#parse_with' do
50
- let(:xml) { '<xml></xml>' }
51
-
52
- it 'invokes the parser and passes the xml' do
53
- parser = double 'Parser', parse: nil
54
- parser.should_receive(:parse).with xml
55
- Feedzirra::Feed.parse_with parser, xml
56
- end
57
-
58
- context 'with a callback block' do
59
- it 'passes the callback to the parser' do
60
- callback = ->(*) { raise Hell }
61
-
62
- expect do
63
- Feedzirra::Feed.parse_with FailParser, xml, &callback
64
- end.to raise_error Hell
65
- end
66
- end
67
- end
68
-
69
- describe "#parse" do # many of these tests are redundant with the specific feed type tests, but I put them here for completeness
70
- context "when there's an available parser" do
71
- it "should parse an rdf feed" do
72
- feed = Feedzirra::Feed.parse(sample_rdf_feed)
73
- feed.title.should == "HREF Considered Harmful"
74
- feed.entries.first.published.should == Time.parse_safely("Tue Sep 02 19:50:07 UTC 2008")
75
- feed.entries.size.should == 10
76
- end
77
-
78
- it "should parse an rss feed" do
79
- feed = Feedzirra::Feed.parse(sample_rss_feed)
80
- feed.title.should == "Tender Lovemaking"
81
- feed.entries.first.published.should == Time.parse_safely("Thu Dec 04 17:17:49 UTC 2008")
82
- feed.entries.size.should == 10
83
- end
84
-
85
- it "should parse an atom feed" do
86
- feed = Feedzirra::Feed.parse(sample_atom_feed)
87
- feed.title.should == "Amazon Web Services Blog"
88
- feed.entries.first.published.should == Time.parse_safely("Fri Jan 16 18:21:00 UTC 2009")
89
- feed.entries.size.should == 10
90
- end
91
-
92
- it "should parse an feedburner atom feed" do
93
- feed = Feedzirra::Feed.parse(sample_feedburner_atom_feed)
94
- feed.title.should == "Paul Dix Explains Nothing"
95
- feed.entries.first.published.should == Time.parse_safely("Thu Jan 22 15:50:22 UTC 2009")
96
- feed.entries.size.should == 5
97
- end
98
-
99
- it "should parse an itunes feed" do
100
- feed = Feedzirra::Feed.parse(sample_itunes_feed)
101
- feed.title.should == "All About Everything"
102
- feed.entries.first.published.should == Time.parse_safely("Wed, 15 Jun 2005 19:00:00 GMT")
103
- feed.entries.size.should == 3
104
- end
105
- end
106
-
107
- context "when there's no available parser" do
108
- it "raises Feedzirra::NoParserAvailable" do
109
- proc {
110
- Feedzirra::Feed.parse("I'm an invalid feed")
111
- }.should raise_error(Feedzirra::NoParserAvailable)
112
- end
113
- end
114
-
115
- it "should parse an feedburner rss feed" do
116
- feed = Feedzirra::Feed.parse(sample_rss_feed_burner_feed)
117
- feed.title.should == "TechCrunch"
118
- feed.entries.first.published.should == Time.parse_safely("Wed Nov 02 17:25:27 UTC 2011")
119
- feed.entries.size.should == 20
120
- end
121
- end
122
-
123
- describe "#determine_feed_parser_for_xml" do
124
- it 'should return the Feedzirra::Parser::GoogleDocsAtom calss for a Google Docs atom feed' do
125
- Feedzirra::Feed.determine_feed_parser_for_xml(sample_google_docs_list_feed).should == Feedzirra::Parser::GoogleDocsAtom
126
- end
127
-
128
- it "should return the Feedzirra::Parser::Atom class for an atom feed" do
129
- Feedzirra::Feed.determine_feed_parser_for_xml(sample_atom_feed).should == Feedzirra::Parser::Atom
130
- end
131
-
132
- it "should return the Feedzirra::Parser::AtomFeedBurner class for an atom feedburner feed" do
133
- Feedzirra::Feed.determine_feed_parser_for_xml(sample_feedburner_atom_feed).should == Feedzirra::Parser::AtomFeedBurner
134
- end
135
-
136
- it "should return the Feedzirra::Parser::RSS class for an rdf/rss 1.0 feed" do
137
- Feedzirra::Feed.determine_feed_parser_for_xml(sample_rdf_feed).should == Feedzirra::Parser::RSS
138
- end
139
-
140
- it "should return the Feedzirra::Parser::RSSFeedBurner class for an rss feedburner feed" do
141
- Feedzirra::Feed.determine_feed_parser_for_xml(sample_rss_feed_burner_feed).should == Feedzirra::Parser::RSSFeedBurner
142
- end
143
-
144
- it "should return the Feedzirra::Parser::RSS object for an rss 2.0 feed" do
145
- Feedzirra::Feed.determine_feed_parser_for_xml(sample_rss_feed).should == Feedzirra::Parser::RSS
146
- end
147
-
148
- it "should return a Feedzirra::Parser::RSS object for an itunes feed" do
149
- Feedzirra::Feed.determine_feed_parser_for_xml(sample_itunes_feed).should == Feedzirra::Parser::ITunesRSS
150
- end
151
-
152
- end
153
-
154
- describe "#setup_easy" do
155
- class MockCurl
156
- attr_accessor :follow_location, :userpwd, :proxy_url, :proxy_port, :max_redirects, :timeout, :ssl_verify_host, :ssl_verify_peer, :ssl_version, :enable_cookies, :cookiefile, :cookies
157
-
158
- def headers
159
- @headers ||= {}
160
- end
161
- end
162
-
163
- let(:curl) { MockCurl.new }
164
-
165
- it "sets defaults on curl" do
166
- Feedzirra::Feed.setup_easy curl
167
-
168
- curl.headers["User-Agent"].should eq Feedzirra::Feed::USER_AGENT
169
- curl.follow_location.should eq true
170
- end
171
-
172
- it "allows user agent over-ride" do
173
- Feedzirra::Feed.setup_easy(curl, user_agent: '007')
174
- curl.headers["User-Agent"].should eq '007'
175
- end
176
-
177
- it "enables compression" do
178
- Feedzirra::Feed.setup_easy(curl, compress: true)
179
- curl.headers["Accept-encoding"].should eq 'gzip, deflate'
180
- end
181
-
182
- it "enables compression even when you act like you don't want it" do
183
- Feedzirra::Feed.setup_easy(curl, compress: false)
184
- curl.headers["Accept-encoding"].should eq 'gzip, deflate'
185
- end
186
-
187
- it "sets up http auth" do
188
- Feedzirra::Feed.setup_easy(curl, http_authentication: ['user', 'pass'])
189
- curl.userpwd.should eq 'user:pass'
190
- end
191
-
192
- it "passes known options to curl" do
193
- known_options = {
194
- enable_cookies: true,
195
- cookiefile: 'cookies.txt',
196
- cookies: 'asdf',
197
- proxy_url: 'http://proxy.url.com',
198
- proxy_port: '1234',
199
- max_redirects: 2,
200
- timeout: 500,
201
- ssl_verify_host: true,
202
- ssl_verify_peer: true,
203
- ssl_version: :omg
204
- }
205
-
206
- Feedzirra::Feed.setup_easy curl, known_options
207
-
208
- known_options.each do |option|
209
- key, value = option
210
- curl.send(key).should eq value
211
- end
212
- end
213
-
214
- it "ignores unknown options" do
215
- expect { Feedzirra::Feed.setup_easy curl, foo: :bar }.to_not raise_error
216
- end
217
- end
218
-
219
- describe "when adding feed types" do
220
- it "should prioritize added types over the built in ones" do
221
- feed_text = "Atom asdf"
222
- Feedzirra::Parser::Atom.stub(:able_to_parse?).and_return(true)
223
- new_feed_type = Class.new do
224
- def self.able_to_parse?(val)
225
- true
226
- end
227
- end
228
-
229
- new_feed_type.should be_able_to_parse(feed_text)
230
- Feedzirra::Feed.add_feed_class(new_feed_type)
231
- Feedzirra::Feed.determine_feed_parser_for_xml(feed_text).should == new_feed_type
232
-
233
- # this is a hack so that this doesn't break the rest of the tests
234
- Feedzirra::Feed.feed_classes.reject! {|o| o == new_feed_type }
235
- end
236
- end
237
-
238
- describe '#etag_from_header' do
239
- before(:each) do
240
- @header = "HTTP/1.0 200 OK\r\nDate: Thu, 29 Jan 2009 03:55:24 GMT\r\nServer: Apache\r\nX-FB-Host: chi-write6\r\nLast-Modified: Wed, 28 Jan 2009 04:10:32 GMT\r\nETag: ziEyTl4q9GH04BR4jgkImd0GvSE\r\nP3P: CP=\"ALL DSP COR NID CUR OUR NOR\"\r\nConnection: close\r\nContent-Type: text/xml;charset=utf-8\r\n\r\n"
241
- end
242
-
243
- it "should return the etag from the header if it exists" do
244
- Feedzirra::Feed.etag_from_header(@header).should == "ziEyTl4q9GH04BR4jgkImd0GvSE"
245
- end
246
-
247
- it "should return nil if there is no etag in the header" do
248
- Feedzirra::Feed.etag_from_header("foo").should be_nil
249
- end
250
-
251
- end
252
-
253
- describe '#last_modified_from_header' do
254
- before(:each) do
255
- @header = "HTTP/1.0 200 OK\r\nDate: Thu, 29 Jan 2009 03:55:24 GMT\r\nServer: Apache\r\nX-FB-Host: chi-write6\r\nLast-Modified: Wed, 28 Jan 2009 04:10:32 GMT\r\nETag: ziEyTl4q9GH04BR4jgkImd0GvSE\r\nP3P: CP=\"ALL DSP COR NID CUR OUR NOR\"\r\nConnection: close\r\nContent-Type: text/xml;charset=utf-8\r\n\r\n"
256
- end
257
-
258
- it "should return the last modified date from the header if it exists" do
259
- Feedzirra::Feed.last_modified_from_header(@header).should == Time.parse_safely("Wed, 28 Jan 2009 04:10:32 GMT")
260
- end
261
-
262
- it "should return nil if there is no last modified date in the header" do
263
- Feedzirra::Feed.last_modified_from_header("foo").should be_nil
264
- end
265
- end
266
-
267
- describe "fetching feeds" do
268
- before(:each) do
269
- @paul_feed = { :xml => load_sample("PaulDixExplainsNothing.xml"), :url => "http://feeds.feedburner.com/PaulDixExplainsNothing" }
270
- @trotter_feed = { :xml => load_sample("TrotterCashionHome.xml"), :url => "http://feeds2.feedburner.com/trottercashion" }
271
- @invalid_feed = { :xml => 'This feed is invalid', :url => "http://feeds.feedburner.com/InvalidFeed" }
272
- end
273
-
274
- describe "#fetch_raw" do
275
- before(:each) do
276
- @cmock = double('cmock', :header_str => '', :body_str => @paul_feed[:xml] )
277
- @multi = double('curl_multi', :add => true, :perform => true)
278
- @curl_easy = double('curl_easy')
279
- @curl = double('curl', :headers => {}, :follow_location= => true, :on_failure => true, :on_complete => true)
280
- @curl.stub(:on_success).and_yield(@cmock)
281
-
282
- Curl::Multi.stub(:new).and_return(@multi)
283
- Curl::Easy.stub(:new).and_yield(@curl).and_return(@curl_easy)
284
- end
285
-
286
- it "should set user agent if it's passed as an option" do
287
- Feedzirra::Feed.fetch_raw(@paul_feed[:url], :user_agent => 'Custom Useragent')
288
- @curl.headers['User-Agent'].should == 'Custom Useragent'
289
- end
290
-
291
- it "should set user agent to default if it's not passed as an option" do
292
- Feedzirra::Feed.fetch_raw(@paul_feed[:url])
293
- @curl.headers['User-Agent'].should == Feedzirra::Feed::USER_AGENT
294
- end
295
-
296
- it "should set if modified since as an option if passed" do
297
- Feedzirra::Feed.fetch_raw(@paul_feed[:url], :if_modified_since => Time.parse_safely("Wed, 28 Jan 2009 04:10:32 GMT"))
298
- @curl.headers["If-Modified-Since"].should == 'Wed, 28 Jan 2009 04:10:32 GMT'
299
- end
300
-
301
- it "should set if none match as an option if passed" do
302
- Feedzirra::Feed.fetch_raw(@paul_feed[:url], :if_none_match => 'ziEyTl4q9GH04BR4jgkImd0GvSE')
303
- @curl.headers["If-None-Match"].should == 'ziEyTl4q9GH04BR4jgkImd0GvSE'
304
- end
305
-
306
- it 'should set userpwd for http basic authentication if :http_authentication is passed' do
307
- @curl.should_receive(:userpwd=).with('username:password')
308
- Feedzirra::Feed.fetch_raw(@paul_feed[:url], :http_authentication => ['username', 'password'])
309
- end
310
-
311
- it 'should set accepted encodings' do
312
- Feedzirra::Feed.fetch_raw(@paul_feed[:url], :compress => true)
313
- @curl.headers["Accept-encoding"].should == 'gzip, deflate'
314
- end
315
-
316
- it "should return raw xml" do
317
- Feedzirra::Feed.fetch_raw(@paul_feed[:url]).should =~ /^#{Regexp.escape('<?xml version="1.0" encoding="UTF-8"?>')}/
318
- end
319
-
320
- it "should take multiple feed urls and return a hash of urls and response xml" do
321
- multi = double('curl_multi', :add => true, :perform => true)
322
- Curl::Multi.stub(:new).and_return(multi)
323
-
324
- paul_response = double('paul_response', :header_str => '', :body_str => @paul_feed[:xml] )
325
- trotter_response = double('trotter_response', :header_str => '', :body_str => @trotter_feed[:xml] )
326
-
327
- paul_curl = double('paul_curl', :headers => {}, :follow_location= => true, :on_failure => true, :on_complete => true)
328
- paul_curl.stub(:on_success).and_yield(paul_response)
329
-
330
- trotter_curl = double('trotter_curl', :headers => {}, :follow_location= => true, :on_failure => true, :on_complete => true)
331
- trotter_curl.stub(:on_success).and_yield(trotter_response)
332
-
333
- Curl::Easy.should_receive(:new).with(@paul_feed[:url]).ordered.and_yield(paul_curl)
334
- Curl::Easy.should_receive(:new).with(@trotter_feed[:url]).ordered.and_yield(trotter_curl)
335
-
336
- results = Feedzirra::Feed.fetch_raw([@paul_feed[:url], @trotter_feed[:url]])
337
- results.keys.should include(@paul_feed[:url])
338
- results.keys.should include(@trotter_feed[:url])
339
- results[@paul_feed[:url]].should =~ /Paul Dix/
340
- results[@trotter_feed[:url]].should =~ /Trotter Cashion/
341
- end
342
-
343
- it "should always return a hash when passed an array" do
344
- results = Feedzirra::Feed.fetch_raw([@paul_feed[:url]])
345
- results.class.should == Hash
346
- end
347
- end
348
-
349
- describe "#add_url_to_multi" do
350
- before(:each) do
351
- allow_message_expectations_on_nil
352
- @multi = Curl::Multi.get([@paul_feed[:url]], {:follow_location => true}, {:pipeline => true})
353
- @multi.stub(:add)
354
- @easy_curl = Curl::Easy.new(@paul_feed[:url])
355
-
356
- Curl::Easy.should_receive(:new).and_yield(@easy_curl)
357
- end
358
-
359
- it "should set user agent if it's passed as an option" do
360
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, :user_agent => 'My cool application')
361
- @easy_curl.headers["User-Agent"].should == 'My cool application'
362
- end
363
-
364
- it "should set user agent to default if it's not passed as an option" do
365
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, {})
366
- @easy_curl.headers["User-Agent"].should == Feedzirra::Feed::USER_AGENT
367
- end
368
-
369
- it "should set if modified since as an option if passed" do
370
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, :if_modified_since => Time.parse_safely("Jan 25 2009 04:10:32 GMT"))
371
- @easy_curl.headers["If-Modified-Since"].should == 'Sun, 25 Jan 2009 04:10:32 GMT'
372
- end
373
-
374
- it 'should set follow location to true' do
375
- @easy_curl.should_receive(:follow_location=).with(true)
376
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, {})
377
- end
378
-
379
- it 'should set userpwd for http basic authentication if :http_authentication is passed' do
380
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, :http_authentication => ['myusername', 'mypassword'])
381
- @easy_curl.userpwd.should == 'myusername:mypassword'
382
- end
383
-
384
- it 'should set accepted encodings' do
385
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, {:compress => true})
386
- @easy_curl.headers["Accept-encoding"].should == 'gzip, deflate'
387
- end
388
-
389
- it "should set if_none_match as an option if passed" do
390
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, :if_none_match => 'ziEyTl4q9GH04BR4jgkImd0GvSE')
391
- @easy_curl.headers["If-None-Match"].should == 'ziEyTl4q9GH04BR4jgkImd0GvSE'
392
- end
393
-
394
- describe 'on success' do
395
- before(:each) do
396
- @feed = double('feed', :feed_url= => true, :etag= => true, :last_modified= => true)
397
- Feedzirra::Feed.stub(:decode_content).and_return(@paul_feed[:xml])
398
- Feedzirra::Feed.stub(:determine_feed_parser_for_xml).and_return(Feedzirra::Parser::AtomFeedBurner)
399
- Feedzirra::Parser::AtomFeedBurner.stub(:parse).and_return(@feed)
400
- Feedzirra::Feed.stub(:etag_from_header).and_return('ziEyTl4q9GH04BR4jgkImd0GvSE')
401
- Feedzirra::Feed.stub(:last_modified_from_header).and_return('Wed, 28 Jan 2009 04:10:32 GMT')
402
- end
403
-
404
- it 'should decode the response body' do
405
- Feedzirra::Feed.should_receive(:decode_content).with(@easy_curl).and_return(@paul_feed[:xml])
406
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, {})
407
- @easy_curl.on_success.call(@easy_curl)
408
- end
409
-
410
- it 'should determine the xml parser class' do
411
- Feedzirra::Feed.should_receive(:determine_feed_parser_for_xml).with(@paul_feed[:xml]).and_return(Feedzirra::Parser::AtomFeedBurner)
412
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, {})
413
- @easy_curl.on_success.call(@easy_curl)
414
- end
415
-
416
- it 'should parse the xml' do
417
- Feedzirra::Parser::AtomFeedBurner.should_receive(:parse).
418
- with(@paul_feed[:xml]).and_return(@feed)
419
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, {})
420
- @easy_curl.on_success.call(@easy_curl)
421
- end
422
-
423
- describe 'when a compatible xml parser class is found' do
424
- it 'should set the last effective url to the feed url' do
425
- @easy_curl.should_receive(:last_effective_url).and_return(@paul_feed[:url])
426
- @feed.should_receive(:feed_url=).with(@paul_feed[:url])
427
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, {})
428
- @easy_curl.on_success.call(@easy_curl)
429
- end
430
-
431
- it 'should set the etags on the feed' do
432
- @feed.should_receive(:etag=).with('ziEyTl4q9GH04BR4jgkImd0GvSE')
433
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, {})
434
- @easy_curl.on_success.call(@easy_curl)
435
- end
436
-
437
- it 'should set the last modified on the feed' do
438
- @feed.should_receive(:last_modified=).with('Wed, 28 Jan 2009 04:10:32 GMT')
439
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, {})
440
- @easy_curl.on_success.call(@easy_curl)
441
- end
442
-
443
- it 'should add the feed to the responses' do
444
- responses = {}
445
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], responses, {})
446
- @easy_curl.on_success.call(@easy_curl)
447
-
448
- responses.length.should == 1
449
- responses['http://feeds.feedburner.com/PaulDixExplainsNothing'].should == @feed
450
- end
451
-
452
- it 'should call proc if :on_success option is passed' do
453
- success = lambda { |url, feed| }
454
- success.should_receive(:call).with(@paul_feed[:url], @feed)
455
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, { :on_success => success })
456
- @easy_curl.on_success.call(@easy_curl)
457
- end
458
-
459
- describe 'when the parser raises an exception' do
460
- it 'invokes the on_failure callback with that exception' do
461
- failure = double 'Failure callback', arity: 2
462
- failure.should_receive(:call).with(@easy_curl, an_instance_of(Hell))
463
-
464
- Feedzirra::Parser::AtomFeedBurner.should_receive(:parse).and_raise Hell
465
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, { on_failure: failure })
466
-
467
- @easy_curl.on_success.call(@easy_curl)
468
- end
469
- end
470
-
471
- describe 'when the parser invokes its on_failure callback' do
472
- before(:each) do
473
- Feedzirra::Feed.stub(:determine_feed_parser_for_xml).and_return FailParser
474
- end
475
-
476
- it 'invokes the on_failure callback' do
477
- failure = double 'Failure callback', arity: 2
478
- failure.should_receive(:call).with(@easy_curl, an_instance_of(RuntimeError))
479
-
480
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, { on_failure: failure })
481
- @easy_curl.on_success.call(@easy_curl)
482
- end
483
- end
484
- end
485
-
486
- describe 'when no compatible xml parser class is found' do
487
- it 'invokes the on_failure callback' do
488
- failure = double 'Failure callback', arity: 2
489
- failure.should_receive(:call).with(@easy_curl, "Can't determine a parser")
490
-
491
- Feedzirra::Feed.should_receive(:determine_feed_parser_for_xml).and_return nil
492
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, { on_failure: failure })
493
-
494
- @easy_curl.on_success.call(@easy_curl)
495
- end
496
- end
497
- end
498
-
499
- describe 'on failure' do
500
- before(:each) do
501
- @headers = "HTTP/1.0 500 Something Bad\r\nDate: Thu, 29 Jan 2009 03:55:24 GMT\r\nServer: Apache\r\nX-FB-Host: chi-write6\r\nLast-Modified: Wed, 28 Jan 2009 04:10:32 GMT\r\n"
502
- @body = 'Sorry, something broke'
503
-
504
- @easy_curl.stub(:response_code).and_return(500)
505
- @easy_curl.stub(:header_str).and_return(@headers)
506
- @easy_curl.stub(:body_str).and_return(@body)
507
- end
508
-
509
- it 'should call proc if :on_failure option is passed' do
510
- failure = double 'Failure callback', arity: 2
511
- failure.should_receive(:call).with(@easy_curl, nil)
512
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, { :on_failure => failure })
513
- @easy_curl.on_failure.call(@easy_curl)
514
- end
515
-
516
- it 'should return the http code in the responses' do
517
- responses = {}
518
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], responses, {})
519
- @easy_curl.on_failure.call(@easy_curl)
520
-
521
- responses.length.should == 1
522
- responses[@paul_feed[:url]].should == 500
523
- end
524
- end
525
-
526
- describe 'on complete for 404s' do
527
- before(:each) do
528
- @headers = "HTTP/1.0 404 Not Found\r\nDate: Thu, 29 Jan 2009 03:55:24 GMT\r\nServer: Apache\r\nX-FB-Host: chi-write6\r\nLast-Modified: Wed, 28 Jan 2009 04:10:32 GMT\r\n"
529
- @body = 'Page could not be found.'
530
-
531
- @easy_curl.stub(:response_code).and_return(404)
532
- @easy_curl.stub(:header_str).and_return(@headers)
533
- @easy_curl.stub(:body_str).and_return(@body)
534
- end
535
-
536
- it 'should call proc if :on_failure option is passed' do
537
- complete = double 'Failure callback', arity: 2
538
- complete.should_receive(:call).with(@easy_curl, 'Server returned a 404')
539
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], {}, { :on_failure => complete })
540
- @easy_curl.on_missing.call(@easy_curl)
541
- end
542
-
543
- it 'should return the http code in the responses' do
544
- responses = {}
545
- Feedzirra::Feed.add_url_to_multi(@multi, @paul_feed[:url], [], responses, {})
546
- @easy_curl.on_complete.call(@easy_curl)
547
-
548
- responses.length.should == 1
549
- responses[@paul_feed[:url]].should == 404
550
- end
551
- end
552
- end
553
-
554
- describe "#add_feed_to_multi" do
555
- before(:each) do
556
- allow_message_expectations_on_nil
557
- @multi = Curl::Multi.get([@paul_feed[:url]], {:follow_location => true}, {:pipeline => true})
558
- @multi.stub(:add)
559
- @easy_curl = Curl::Easy.new(@paul_feed[:url])
560
- @feed = Feedzirra::Feed.parse(sample_feedburner_atom_feed)
561
-
562
- Curl::Easy.should_receive(:new).and_yield(@easy_curl)
563
- end
564
-
565
- it "should set user agent if it's passed as an option" do
566
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, :user_agent => 'My cool application')
567
- @easy_curl.headers["User-Agent"].should == 'My cool application'
568
- end
569
-
570
- it "should set user agent to default if it's not passed as an option" do
571
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, {})
572
- @easy_curl.headers["User-Agent"].should == Feedzirra::Feed::USER_AGENT
573
- end
574
-
575
- it "should set if modified since as an option if passed" do
576
- modified_time = Time.parse_safely("Wed, 28 Jan 2009 04:10:32 GMT")
577
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, {:if_modified_since => modified_time})
578
- modified_time.should be > @feed.last_modified
579
-
580
- @easy_curl.headers["If-Modified-Since"].should == modified_time
581
- end
582
-
583
- it 'should set follow location to true' do
584
- @easy_curl.should_receive(:follow_location=).with(true)
585
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, {})
586
- end
587
-
588
- it 'should set userpwd for http basic authentication if :http_authentication is passed' do
589
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, :http_authentication => ['myusername', 'mypassword'])
590
- @easy_curl.userpwd.should == 'myusername:mypassword'
591
- end
592
-
593
- it "should set if_none_match as an option if passed" do
594
- @feed.etag = 'ziEyTl4q9GH04BR4jgkImd0GvSE'
595
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, {})
596
- @easy_curl.headers["If-None-Match"].should == 'ziEyTl4q9GH04BR4jgkImd0GvSE'
597
- end
598
-
599
- describe 'on success' do
600
- before(:each) do
601
- @new_feed = @feed.clone
602
- @feed.stub(:update_from_feed)
603
- Feedzirra::Feed.stub(:decode_content).and_return(@paul_feed[:xml])
604
- Feedzirra::Feed.stub(:determine_feed_parser_for_xml).and_return(Feedzirra::Parser::AtomFeedBurner)
605
- Feedzirra::Parser::AtomFeedBurner.stub(:parse).and_return(@new_feed)
606
- Feedzirra::Feed.stub(:etag_from_header).and_return('ziEyTl4q9GH04BR4jgkImd0GvSE')
607
- Feedzirra::Feed.stub(:last_modified_from_header).and_return('Wed, 28 Jan 2009 04:10:32 GMT')
608
- end
609
-
610
- it 'should parse the updated feed' do
611
- Feedzirra::Parser::AtomFeedBurner.should_receive(:parse).and_return(@new_feed)
612
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, {})
613
- @easy_curl.on_success.call(@easy_curl)
614
- end
615
-
616
- it 'should set the last effective url to the feed url' do
617
- @easy_curl.should_receive(:last_effective_url).and_return(@paul_feed[:url])
618
- @new_feed.should_receive(:feed_url=).with(@paul_feed[:url])
619
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, {})
620
- @easy_curl.on_success.call(@easy_curl)
621
- end
622
-
623
- it 'should set the etags on the feed' do
624
- @new_feed.should_receive(:etag=).with('ziEyTl4q9GH04BR4jgkImd0GvSE')
625
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, {})
626
- @easy_curl.on_success.call(@easy_curl)
627
- end
628
-
629
- it 'should set the last modified on the feed' do
630
- @new_feed.should_receive(:last_modified=).with('Wed, 28 Jan 2009 04:10:32 GMT')
631
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, {})
632
- @easy_curl.on_success.call(@easy_curl)
633
- end
634
-
635
- it 'should add the feed to the responses' do
636
- responses = {}
637
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], responses, {})
638
- @easy_curl.on_success.call(@easy_curl)
639
-
640
- responses.length.should == 1
641
- responses['http://feeds.feedburner.com/PaulDixExplainsNothing'].should == @feed
642
- end
643
-
644
- it 'should call proc if :on_success option is passed' do
645
- success = lambda { |feed| }
646
- success.should_receive(:call).with(@feed)
647
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, { :on_success => success })
648
- @easy_curl.on_success.call(@easy_curl)
649
- end
650
-
651
- it 'should call update from feed on the old feed with the updated feed' do
652
- @feed.should_receive(:update_from_feed).with(@new_feed)
653
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, {})
654
- @easy_curl.on_success.call(@easy_curl)
655
- end
656
-
657
- describe 'when the parser invokes its on_failure callback' do
658
- before(:each) do
659
- Feedzirra::Feed.stub(:determine_feed_parser_for_xml).and_return FailParser
660
- end
661
-
662
- it 'invokes the on_failure callback' do
663
- failure = double 'Failure callback', arity: 2
664
- failure.should_receive(:call)
665
-
666
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, { on_failure: failure })
667
- @easy_curl.on_success.call(@easy_curl)
668
- end
669
- end
670
- end
671
-
672
- describe 'on failure' do
673
- before(:each) do
674
- @headers = "HTTP/1.0 404 Not Found\r\nDate: Thu, 29 Jan 2009 03:55:24 GMT\r\nServer: Apache\r\nX-FB-Host: chi-write6\r\nLast-Modified: Wed, 28 Jan 2009 04:10:32 GMT\r\n"
675
- @body = 'Page could not be found.'
676
-
677
- @easy_curl.stub(:response_code).and_return(404)
678
- @easy_curl.stub(:header_str).and_return(@headers)
679
- @easy_curl.stub(:body_str).and_return(@body)
680
- end
681
-
682
- it 'should call on success callback if the response code is 304' do
683
- success = lambda { |feed| }
684
- success.should_receive(:call).with(@feed)
685
- @easy_curl.should_receive(:response_code).and_return(304)
686
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], {}, { :on_success => success })
687
- @easy_curl.on_redirect.call(@easy_curl)
688
- end
689
-
690
- it 'should return the http code in the responses' do
691
- responses = {}
692
- Feedzirra::Feed.add_feed_to_multi(@multi, @feed, [], responses, {})
693
- @easy_curl.on_failure.call(@easy_curl)
694
-
695
- responses.length.should == 1
696
- responses[@paul_feed[:url]].should == 404
697
- end
698
- end
699
- end
700
-
701
- describe "#fetch_and_parse" do
702
- it "passes options to multicurl" do
703
- options = { user_agent: '007' }
704
-
705
- Feedzirra::Feed.should_receive(:add_url_to_multi).
706
- with(anything, anything, anything, anything, options)
707
-
708
- Feedzirra::Feed.fetch_and_parse(sample_rss_feed, options)
709
- end
710
- end
711
-
712
- describe "#decode_content" do
713
- before(:each) do
714
- @curl_easy = double('curl_easy', :body_str => '<xml></xml>')
715
- end
716
-
717
- it 'should decode the response body using gzip if the Content-Encoding: is gzip' do
718
- @curl_easy.stub(:header_str).and_return('Content-Encoding: gzip')
719
- string_io = double('stringio', :read => @curl_easy.body_str, :close => true)
720
- StringIO.should_receive(:new).and_return(string_io)
721
- Zlib::GzipReader.should_receive(:new).with(string_io).and_return(string_io)
722
- Feedzirra::Feed.decode_content(@curl_easy)
723
- end
724
-
725
- it 'should decode the response body using gzip if the Content-Encoding: is gzip even when the case is wrong' do
726
- @curl_easy.stub(:header_str).and_return('content-encoding: gzip')
727
- string_io = double('stringio', :read => @curl_easy.body_str, :close => true)
728
- StringIO.should_receive(:new).and_return(string_io)
729
- Zlib::GzipReader.should_receive(:new).with(string_io).and_return(string_io)
730
- Feedzirra::Feed.decode_content(@curl_easy)
731
- end
732
-
733
- it 'should deflate the response body using inflate if the Content-Encoding: is deflate' do
734
- @curl_easy.stub(:header_str).and_return('Content-Encoding: deflate')
735
- Zlib::Inflate.should_receive(:inflate).with(@curl_easy.body_str)
736
- Feedzirra::Feed.decode_content(@curl_easy)
737
- end
738
-
739
- it 'should deflate the response body using inflate if the Content-Encoding: is deflate event if the case is wrong' do
740
- @curl_easy.stub(:header_str).and_return('content-encoding: deflate')
741
- Zlib::Inflate.should_receive(:inflate).with(@curl_easy.body_str)
742
- Feedzirra::Feed.decode_content(@curl_easy)
743
- end
744
-
745
- it 'should return the response body if it is not encoded' do
746
- @curl_easy.stub(:header_str).and_return('')
747
- Feedzirra::Feed.decode_content(@curl_easy).should == '<xml></xml>'
748
- end
749
- end
750
-
751
- describe "#update" do
752
- it "passes options to multicurl" do
753
- options = { user_agent: '007' }
754
-
755
- Feedzirra::Feed.should_receive(:add_feed_to_multi).
756
- with(anything, anything, anything, anything, options)
757
-
758
- Feedzirra::Feed.update(sample_rss_feed, options)
759
- end
760
- end
761
- end
762
- end