feedjira 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +31 -12
- data/CHANGELOG.md +15 -1
- data/Dangerfile +1 -0
- data/Gemfile +2 -1
- data/Rakefile +6 -1
- data/feedjira.gemspec +16 -14
- data/fixtures/vcr_cassettes/fetch_failure.yml +62 -0
- data/fixtures/vcr_cassettes/parse_error.yml +222 -0
- data/fixtures/vcr_cassettes/success.yml +281 -0
- data/lib/feedjira.rb +9 -0
- data/lib/feedjira/core_ext.rb +3 -3
- data/lib/feedjira/core_ext/date.rb +2 -1
- data/lib/feedjira/core_ext/string.rb +1 -1
- data/lib/feedjira/core_ext/time.rb +19 -16
- data/lib/feedjira/date_time_utilities.rb +24 -0
- data/lib/feedjira/date_time_utilities/date_time_language_parser.rb +22 -0
- data/lib/feedjira/date_time_utilities/date_time_pattern_parser.rb +29 -0
- data/lib/feedjira/feed.rb +27 -18
- data/lib/feedjira/feed_entry_utilities.rb +15 -17
- data/lib/feedjira/feed_utilities.rb +26 -21
- data/lib/feedjira/parser/atom.rb +9 -8
- data/lib/feedjira/parser/atom_entry.rb +10 -13
- data/lib/feedjira/parser/atom_feed_burner.rb +8 -10
- data/lib/feedjira/parser/atom_feed_burner_entry.rb +11 -14
- data/lib/feedjira/parser/atom_youtube.rb +20 -0
- data/lib/feedjira/parser/atom_youtube_entry.rb +29 -0
- data/lib/feedjira/parser/google_docs_atom.rb +6 -6
- data/lib/feedjira/parser/google_docs_atom_entry.rb +11 -11
- data/lib/feedjira/parser/itunes_rss.rb +39 -22
- data/lib/feedjira/parser/itunes_rss_category.rb +38 -0
- data/lib/feedjira/parser/itunes_rss_item.rb +28 -20
- data/lib/feedjira/parser/itunes_rss_owner.rb +3 -4
- data/lib/feedjira/parser/podlove_chapter.rb +20 -0
- data/lib/feedjira/parser/rss.rb +10 -8
- data/lib/feedjira/parser/rss_entry.rb +17 -21
- data/lib/feedjira/parser/rss_feed_burner.rb +4 -6
- data/lib/feedjira/parser/rss_feed_burner_entry.rb +23 -28
- data/lib/feedjira/parser/rss_image.rb +15 -0
- data/lib/feedjira/preprocessor.rb +2 -2
- data/lib/feedjira/version.rb +1 -1
- data/spec/feedjira/date_time_utilities_spec.rb +41 -0
- data/spec/feedjira/feed_entry_utilities_spec.rb +23 -19
- data/spec/feedjira/feed_spec.rb +109 -74
- data/spec/feedjira/feed_utilities_spec.rb +65 -63
- data/spec/feedjira/parser/atom_entry_spec.rb +54 -34
- data/spec/feedjira/parser/atom_feed_burner_entry_spec.rb +27 -20
- data/spec/feedjira/parser/atom_feed_burner_spec.rb +32 -30
- data/spec/feedjira/parser/atom_spec.rb +50 -48
- data/spec/feedjira/parser/atom_youtube_entry_spec.rb +86 -0
- data/spec/feedjira/parser/atom_youtube_spec.rb +43 -0
- data/spec/feedjira/parser/google_docs_atom_entry_spec.rb +5 -4
- data/spec/feedjira/parser/google_docs_atom_spec.rb +6 -6
- data/spec/feedjira/parser/itunes_rss_item_spec.rb +33 -29
- data/spec/feedjira/parser/itunes_rss_owner_spec.rb +10 -9
- data/spec/feedjira/parser/itunes_rss_spec.rb +83 -30
- data/spec/feedjira/parser/podlove_chapter_spec.rb +37 -0
- data/spec/feedjira/parser/rss_entry_spec.rb +50 -33
- data/spec/feedjira/parser/rss_feed_burner_entry_spec.rb +55 -33
- data/spec/feedjira/parser/rss_feed_burner_spec.rb +31 -26
- data/spec/feedjira/parser/rss_spec.rb +56 -24
- data/spec/feedjira/preprocessor_spec.rb +11 -3
- data/spec/sample_feeds.rb +29 -21
- data/spec/sample_feeds/AmazonWebServicesBlog.xml +797 -797
- data/spec/sample_feeds/AtomEscapedHTMLInPreTag.xml +13 -0
- data/spec/sample_feeds/CRE.xml +5849 -0
- data/spec/sample_feeds/FeedBurnerXHTML.xml +400 -400
- data/spec/sample_feeds/ITunesWithSingleQuotedAttributes.xml +67 -0
- data/spec/sample_feeds/PaulDixExplainsNothing.xml +175 -175
- data/spec/sample_feeds/PaulDixExplainsNothingAlternate.xml +175 -175
- data/spec/sample_feeds/PaulDixExplainsNothingFirstEntryContent.xml +16 -16
- data/spec/sample_feeds/PaulDixExplainsNothingWFW.xml +174 -174
- data/spec/sample_feeds/TenderLovemaking.xml +12 -2
- data/spec/sample_feeds/TrotterCashionHome.xml +611 -611
- data/spec/sample_feeds/TypePadNews.xml +368 -368
- data/spec/sample_feeds/itunes.xml +18 -2
- data/spec/sample_feeds/pet_atom.xml +229 -229
- data/spec/sample_feeds/youtube_atom.xml +395 -0
- data/spec/spec_helper.rb +6 -0
- metadata +112 -27
@@ -18,11 +18,11 @@ module Feedjira
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def content_nodes
|
21
|
-
doc.search 'entry > content[type="xhtml"], entry > summary[type="xhtml"], entry > title[type="xhtml"]'
|
21
|
+
doc.search 'entry > content[type="xhtml"], entry > summary[type="xhtml"], entry > title[type="xhtml"]' # rubocop:disable Metrics/LineLength
|
22
22
|
end
|
23
23
|
|
24
24
|
def raw_html(node)
|
25
|
-
|
25
|
+
node.search('./div').inner_html
|
26
26
|
end
|
27
27
|
|
28
28
|
def doc
|
data/lib/feedjira/version.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Feedjira::FeedUtilities do
|
4
|
+
before(:each) do
|
5
|
+
@klass = Class.new do
|
6
|
+
include Feedjira::DateTimeUtilities
|
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
|
+
expect(time.class).to eq Time
|
14
|
+
expect(time).to eq 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
|
+
expect(time.class).to eq Time
|
20
|
+
expect(time).to eq Time.parse_safely('Tue Sep 17 12:20:13 UTC 2013')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should parse a US Format into Time' do
|
24
|
+
time = @klass.new.parse_datetime('8/23/2016 12:29:58 PM')
|
25
|
+
expect(time.class).to eq Time
|
26
|
+
expect(time).to eq Time.parse_safely('Wed Aug 23 12:29:58 UTC 2016')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should parse a Spanish Format into Time' do
|
30
|
+
time = @klass.new.parse_datetime('Wed, 31 Ago 2016 11:08:22 GMT')
|
31
|
+
expect(time.class).to eq Time
|
32
|
+
expect(time).to eq Time.parse_safely('Wed Aug 31 11:08:22 UTC 2016')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should parse Format with japanese symbols into Time' do
|
36
|
+
time = @klass.new.parse_datetime('水, 31 8 2016 07:37:00 PDT')
|
37
|
+
expect(time.class).to eq Time
|
38
|
+
expect(time).to eq Time.parse_safely('Wed Aug 31 14:37:00 UTC 2016')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -7,21 +7,21 @@ describe Feedjira::FeedUtilities do
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
describe
|
11
|
-
it
|
12
|
-
time = @klass.new.parse_datetime(
|
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
13
|
expect(time.class).to eq Time
|
14
|
-
expect(time).to eq Time.parse_safely(
|
14
|
+
expect(time).to eq Time.parse_safely('Wed Feb 20 18:05:00 UTC 2008')
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
18
|
-
time = @klass.new.parse_datetime(
|
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
19
|
expect(time.class).to eq Time
|
20
|
-
expect(time).to eq Time.parse_safely(
|
20
|
+
expect(time).to eq Time.parse_safely('Tue Sep 17 12:20:13 UTC 2013')
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
describe
|
24
|
+
describe 'sanitizing' do
|
25
25
|
before(:each) do
|
26
26
|
@feed = Feedjira::Feed.parse(sample_atom_feed)
|
27
27
|
@entry = @feed.entries.first
|
@@ -31,23 +31,27 @@ describe Feedjira::FeedUtilities do
|
|
31
31
|
expect { @klass.new.sanitize! }.to_not raise_error
|
32
32
|
end
|
33
33
|
|
34
|
-
it
|
35
|
-
new_title =
|
34
|
+
it 'should provide a sanitized title' do
|
35
|
+
new_title = '<script>this is not safe</script>' + @entry.title
|
36
36
|
@entry.title = new_title
|
37
|
-
|
37
|
+
scrubbed_title = Loofah.scrub_fragment(new_title, :prune).to_s
|
38
|
+
expect(@entry.title.sanitize).to eq scrubbed_title
|
38
39
|
end
|
39
40
|
|
40
|
-
it
|
41
|
-
new_content =
|
41
|
+
it 'should sanitize content in place' do
|
42
|
+
new_content = '<script>' + @entry.content
|
42
43
|
@entry.content = new_content.dup
|
43
|
-
|
44
|
-
|
44
|
+
|
45
|
+
scrubbed_content = Loofah.scrub_fragment(new_content, :prune).to_s
|
46
|
+
|
47
|
+
expect(@entry.content.sanitize!).to eq scrubbed_content
|
48
|
+
expect(@entry.content).to eq scrubbed_content
|
45
49
|
end
|
46
50
|
|
47
|
-
it
|
48
|
-
@entry.title +=
|
49
|
-
@entry.author +=
|
50
|
-
@entry.content +=
|
51
|
+
it 'should sanitize things in place' do
|
52
|
+
@entry.title += '<script>'
|
53
|
+
@entry.author += '<script>'
|
54
|
+
@entry.content += '<script>'
|
51
55
|
|
52
56
|
cleaned_title = Loofah.scrub_fragment(@entry.title, :prune).to_s
|
53
57
|
cleaned_author = Loofah.scrub_fragment(@entry.author, :prune).to_s
|
data/spec/feedjira/feed_spec.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# rubocop:disable Style/BlockDelimiters
|
2
4
|
|
3
5
|
class Hell < StandardError; end
|
4
6
|
|
@@ -11,63 +13,72 @@ end
|
|
11
13
|
describe Feedjira::Feed do
|
12
14
|
describe '.fetch_and_parse' do
|
13
15
|
it 'raises an error when the fetch fails' do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
VCR.use_cassette('fetch_failure') do
|
17
|
+
url = 'http://www.example.com/feed.xml'
|
18
|
+
expect {
|
19
|
+
Feedjira::Feed.fetch_and_parse url
|
20
|
+
}.to raise_error Feedjira::FetchFailure
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
it 'raises an error when no parser can be found' do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
+
VCR.use_cassette('parse_error') do
|
26
|
+
url = 'http://feedjira.com'
|
27
|
+
expect {
|
28
|
+
Feedjira::Feed.fetch_and_parse url
|
29
|
+
}.to raise_error Feedjira::NoParserAvailable
|
30
|
+
end
|
25
31
|
end
|
26
32
|
|
27
33
|
it 'fetches and parses the feed' do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
VCR.use_cassette('success') do
|
35
|
+
url = 'http://feedjira.com/blog/feed.xml'
|
36
|
+
expected_time = DateTime.parse('Fri, 07 Oct 2016 14:37:00 GMT').to_time
|
37
|
+
feed = Feedjira::Feed.fetch_and_parse url
|
38
|
+
|
39
|
+
expect(feed.class).to eq Feedjira::Parser::Atom
|
40
|
+
expect(feed.entries.count).to eq 4
|
41
|
+
expect(feed.feed_url).to eq url
|
42
|
+
expect(feed.etag).to eq('393e-53e4757c9db00-gzip')
|
43
|
+
expect(feed.last_modified).to eq(expected_time)
|
44
|
+
end
|
36
45
|
end
|
37
46
|
end
|
38
47
|
|
39
|
-
describe
|
48
|
+
describe '#add_common_feed_element' do
|
40
49
|
before(:all) do
|
41
|
-
Feedjira::Feed.add_common_feed_element(
|
50
|
+
Feedjira::Feed.add_common_feed_element('generator')
|
42
51
|
end
|
43
52
|
|
44
|
-
it
|
45
|
-
expect(Feedjira::Feed.parse(sample_wfw_feed).generator).to eq
|
53
|
+
it 'should parse the added element out of Atom feeds' do
|
54
|
+
expect(Feedjira::Feed.parse(sample_wfw_feed).generator).to eq 'TypePad'
|
46
55
|
end
|
47
56
|
|
48
|
-
it
|
57
|
+
it 'should parse the added element out of Atom Feedburner feeds' do
|
49
58
|
expect(Feedjira::Parser::Atom.new).to respond_to(:generator)
|
50
59
|
end
|
51
60
|
|
52
|
-
it
|
61
|
+
it 'should parse the added element out of RSS feeds' do
|
53
62
|
expect(Feedjira::Parser::RSS.new).to respond_to(:generator)
|
54
63
|
end
|
55
64
|
end
|
56
65
|
|
57
|
-
describe
|
66
|
+
describe '#add_common_feed_entry_element' do
|
58
67
|
before(:all) do
|
59
|
-
|
68
|
+
tag = 'wfw:commentRss'
|
69
|
+
Feedjira::Feed.add_common_feed_entry_element tag, as: :comment_rss
|
60
70
|
end
|
61
71
|
|
62
|
-
it
|
63
|
-
|
72
|
+
it 'should parse the added element out of Atom feeds entries' do
|
73
|
+
entry = Feedjira::Feed.parse(sample_wfw_feed).entries.first
|
74
|
+
expect(entry.comment_rss).to eq 'this is the new val'
|
64
75
|
end
|
65
76
|
|
66
|
-
it
|
77
|
+
it 'should parse the added element out of Atom Feedburner feeds entries' do
|
67
78
|
expect(Feedjira::Parser::AtomEntry.new).to respond_to(:comment_rss)
|
68
79
|
end
|
69
80
|
|
70
|
-
it
|
81
|
+
it 'should parse the added element out of RSS feeds entries' do
|
71
82
|
expect(Feedjira::Parser::RSSEntry.new).to respond_to(:comment_rss)
|
72
83
|
end
|
73
84
|
end
|
@@ -92,107 +103,131 @@ describe Feedjira::Feed do
|
|
92
103
|
end
|
93
104
|
end
|
94
105
|
|
95
|
-
describe
|
106
|
+
describe '#parse' do
|
96
107
|
context "when there's an available parser" do
|
97
|
-
it
|
108
|
+
it 'should parse an rdf feed' do
|
98
109
|
feed = Feedjira::Feed.parse(sample_rdf_feed)
|
99
|
-
expect(feed.title).to eq
|
100
|
-
|
110
|
+
expect(feed.title).to eq 'HREF Considered Harmful'
|
111
|
+
published = Time.parse_safely('Tue Sep 02 19:50:07 UTC 2008')
|
112
|
+
expect(feed.entries.first.published).to eq published
|
101
113
|
expect(feed.entries.size).to eq 10
|
102
114
|
end
|
103
115
|
|
104
|
-
it
|
116
|
+
it 'should parse an rss feed' do
|
105
117
|
feed = Feedjira::Feed.parse(sample_rss_feed)
|
106
|
-
expect(feed.title).to eq
|
107
|
-
|
118
|
+
expect(feed.title).to eq 'Tender Lovemaking'
|
119
|
+
published = Time.parse_safely 'Thu Dec 04 17:17:49 UTC 2008'
|
120
|
+
expect(feed.entries.first.published).to eq published
|
108
121
|
expect(feed.entries.size).to eq 10
|
109
122
|
end
|
110
123
|
|
111
|
-
it
|
124
|
+
it 'should parse an atom feed' do
|
112
125
|
feed = Feedjira::Feed.parse(sample_atom_feed)
|
113
|
-
expect(feed.title).to eq
|
114
|
-
|
126
|
+
expect(feed.title).to eq 'Amazon Web Services Blog'
|
127
|
+
published = Time.parse_safely 'Fri Jan 16 18:21:00 UTC 2009'
|
128
|
+
expect(feed.entries.first.published).to eq published
|
115
129
|
expect(feed.entries.size).to eq 10
|
116
130
|
end
|
117
131
|
|
118
|
-
it
|
132
|
+
it 'should parse an feedburner atom feed' do
|
119
133
|
feed = Feedjira::Feed.parse(sample_feedburner_atom_feed)
|
120
|
-
expect(feed.title).to eq
|
121
|
-
|
134
|
+
expect(feed.title).to eq 'Paul Dix Explains Nothing'
|
135
|
+
published = Time.parse_safely 'Thu Jan 22 15:50:22 UTC 2009'
|
136
|
+
expect(feed.entries.first.published).to eq published
|
122
137
|
expect(feed.entries.size).to eq 5
|
123
138
|
end
|
124
139
|
|
125
|
-
it
|
140
|
+
it 'should parse an itunes feed' do
|
126
141
|
feed = Feedjira::Feed.parse(sample_itunes_feed)
|
127
|
-
expect(feed.title).to eq
|
128
|
-
|
142
|
+
expect(feed.title).to eq 'All About Everything'
|
143
|
+
published = Time.parse_safely 'Wed, 15 Jun 2005 19:00:00 GMT'
|
144
|
+
expect(feed.entries.first.published).to eq published
|
129
145
|
expect(feed.entries.size).to eq 3
|
130
146
|
end
|
131
147
|
end
|
132
148
|
|
133
149
|
context "when there's no available parser" do
|
134
|
-
it
|
150
|
+
it 'raises Feedjira::NoParserAvailable' do
|
135
151
|
expect {
|
136
152
|
Feedjira::Feed.parse("I'm an invalid feed")
|
137
153
|
}.to raise_error(Feedjira::NoParserAvailable)
|
138
154
|
end
|
139
155
|
end
|
140
156
|
|
141
|
-
it
|
157
|
+
it 'should parse an feedburner rss feed' do
|
142
158
|
feed = Feedjira::Feed.parse(sample_rss_feed_burner_feed)
|
143
|
-
expect(feed.title).to eq
|
144
|
-
|
159
|
+
expect(feed.title).to eq 'TechCrunch'
|
160
|
+
published = Time.parse_safely 'Wed Nov 02 17:25:27 UTC 2011'
|
161
|
+
expect(feed.entries.first.published).to eq published
|
145
162
|
expect(feed.entries.size).to eq 20
|
146
163
|
end
|
147
164
|
end
|
148
165
|
|
149
|
-
describe
|
150
|
-
it '
|
151
|
-
|
166
|
+
describe '#determine_feed_parser_for_xml' do
|
167
|
+
it 'with Google Docs atom feed it returns the GoogleDocsAtom parser' do
|
168
|
+
xml = sample_google_docs_list_feed
|
169
|
+
actual_parser = Feedjira::Feed.determine_feed_parser_for_xml xml
|
170
|
+
expect(actual_parser).to eq Feedjira::Parser::GoogleDocsAtom
|
152
171
|
end
|
153
172
|
|
154
|
-
it
|
155
|
-
|
173
|
+
it 'with an atom feed it returns the Atom parser' do
|
174
|
+
xml = sample_atom_feed
|
175
|
+
actual_parser = Feedjira::Feed.determine_feed_parser_for_xml xml
|
176
|
+
expect(actual_parser).to eq Feedjira::Parser::Atom
|
156
177
|
end
|
157
178
|
|
158
|
-
it
|
159
|
-
|
179
|
+
it 'with an atom feedburner feed it returns the AtomFeedBurner parser' do
|
180
|
+
xml = sample_feedburner_atom_feed
|
181
|
+
actual_parser = Feedjira::Feed.determine_feed_parser_for_xml xml
|
182
|
+
expect(actual_parser).to eq Feedjira::Parser::AtomFeedBurner
|
160
183
|
end
|
161
184
|
|
162
|
-
it
|
163
|
-
|
185
|
+
it 'with an rdf feed it returns the RSS parser' do
|
186
|
+
xml = sample_rdf_feed
|
187
|
+
actual_parser = Feedjira::Feed.determine_feed_parser_for_xml xml
|
188
|
+
expect(actual_parser).to eq Feedjira::Parser::RSS
|
164
189
|
end
|
165
190
|
|
166
|
-
it
|
167
|
-
|
191
|
+
it 'with an rss feedburner feed it returns the RSSFeedBurner parser' do
|
192
|
+
xml = sample_rss_feed_burner_feed
|
193
|
+
actual_parser = Feedjira::Feed.determine_feed_parser_for_xml xml
|
194
|
+
expect(actual_parser).to eq Feedjira::Parser::RSSFeedBurner
|
168
195
|
end
|
169
196
|
|
170
|
-
it
|
171
|
-
|
197
|
+
it 'with an rss 2.0 feed it returns the RSS parser' do
|
198
|
+
xml = sample_rss_feed
|
199
|
+
actual_parser = Feedjira::Feed.determine_feed_parser_for_xml xml
|
200
|
+
expect(actual_parser).to eq Feedjira::Parser::RSS
|
172
201
|
end
|
173
202
|
|
174
|
-
it
|
175
|
-
|
203
|
+
it 'with an itunes feed it returns the RSS parser' do
|
204
|
+
xml = sample_itunes_feed
|
205
|
+
actual_parser = Feedjira::Feed.determine_feed_parser_for_xml xml
|
206
|
+
expect(actual_parser).to eq Feedjira::Parser::ITunesRSS
|
176
207
|
end
|
177
|
-
|
178
208
|
end
|
179
209
|
|
180
|
-
describe
|
181
|
-
it
|
182
|
-
|
210
|
+
describe 'when adding feed types' do
|
211
|
+
it 'should prioritize added types over the built in ones' do
|
212
|
+
xml = 'Atom asdf'
|
183
213
|
allow(Feedjira::Parser::Atom).to receive(:able_to_parse?).and_return(true)
|
184
|
-
|
185
|
-
def self.able_to_parse?(
|
214
|
+
new_parser = Class.new do
|
215
|
+
def self.able_to_parse?(_)
|
186
216
|
true
|
187
217
|
end
|
188
218
|
end
|
189
219
|
|
190
|
-
expect(
|
191
|
-
|
192
|
-
|
220
|
+
expect(new_parser).to be_able_to_parse(xml)
|
221
|
+
|
222
|
+
Feedjira::Feed.add_feed_class(new_parser)
|
223
|
+
|
224
|
+
parser = Feedjira::Feed.determine_feed_parser_for_xml xml
|
225
|
+
expect(parser).to eq new_parser
|
193
226
|
|
194
227
|
# this is a hack so that this doesn't break the rest of the tests
|
195
|
-
Feedjira::Feed.feed_classes.reject! {|o| o ==
|
228
|
+
Feedjira::Feed.feed_classes.reject! { |o| o == new_parser }
|
196
229
|
end
|
197
230
|
end
|
198
231
|
end
|
232
|
+
|
233
|
+
# rubocop:enable Style/BlockDelimiters
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Feedjira::FeedUtilities do
|
4
4
|
before(:each) do
|
@@ -8,47 +8,46 @@ describe Feedjira::FeedUtilities do
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
describe
|
12
|
-
context
|
13
|
-
it
|
11
|
+
describe 'preprocessing' do
|
12
|
+
context 'when the flag is not set' do
|
13
|
+
it 'does not call the preprocessing method' do
|
14
14
|
@klass.preprocess_xml = false
|
15
15
|
expect(@klass).to_not receive :preprocess
|
16
16
|
@klass.parse sample_rss_feed
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
context
|
21
|
-
it
|
20
|
+
context 'when the flag is set' do
|
21
|
+
it 'calls the preprocessing method' do
|
22
22
|
@klass.preprocess_xml = true
|
23
|
-
expect(@klass).to receive(:preprocess).
|
24
|
-
and_return sample_rss_feed
|
23
|
+
expect(@klass).to receive(:preprocess).and_return sample_rss_feed
|
25
24
|
@klass.parse sample_rss_feed
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
|
-
describe
|
31
|
-
it
|
29
|
+
describe 'instance methods' do
|
30
|
+
it 'should provide an updated? accessor' do
|
32
31
|
feed = @klass.new
|
33
32
|
expect(feed).to_not be_updated
|
34
33
|
feed.updated = true
|
35
34
|
expect(feed).to be_updated
|
36
35
|
end
|
37
36
|
|
38
|
-
it
|
37
|
+
it 'should provide a new_entries accessor' do
|
39
38
|
feed = @klass.new
|
40
39
|
expect(feed.new_entries).to eq []
|
41
40
|
feed.new_entries = [:foo]
|
42
41
|
expect(feed.new_entries).to eq [:foo]
|
43
42
|
end
|
44
43
|
|
45
|
-
it
|
44
|
+
it 'should provide an etag accessor' do
|
46
45
|
feed = @klass.new
|
47
|
-
feed.etag =
|
48
|
-
expect(feed.etag).to eq
|
46
|
+
feed.etag = 'foo'
|
47
|
+
expect(feed.etag).to eq 'foo'
|
49
48
|
end
|
50
49
|
|
51
|
-
it
|
50
|
+
it 'should provide a last_modified accessor' do
|
52
51
|
feed = @klass.new
|
53
52
|
time = Time.now
|
54
53
|
feed.last_modified = time
|
@@ -56,21 +55,21 @@ describe Feedjira::FeedUtilities do
|
|
56
55
|
expect(feed.last_modified.class).to eq Time
|
57
56
|
end
|
58
57
|
|
59
|
-
it
|
58
|
+
it 'should return new_entries? as true when entries are put into new_entries' do # rubocop:disable Metrics/LineLength
|
60
59
|
feed = @klass.new
|
61
60
|
feed.new_entries << :foo
|
62
|
-
expect(feed).to
|
61
|
+
expect(feed.new_entries?).to eq true
|
63
62
|
end
|
64
63
|
|
65
|
-
it "should return a last_modified value from the entry with the most recent published date if the last_modified date hasn't been set" do
|
64
|
+
it "should return a last_modified value from the entry with the most recent published date if the last_modified date hasn't been set" do # rubocop:disable Metrics/LineLength
|
66
65
|
feed = Feedjira::Parser::Atom.new
|
67
|
-
entry =Feedjira::Parser::AtomEntry.new
|
66
|
+
entry = Feedjira::Parser::AtomEntry.new
|
68
67
|
entry.published = Time.now.to_s
|
69
68
|
feed.entries << entry
|
70
69
|
expect(feed.last_modified).to eq entry.published
|
71
70
|
end
|
72
71
|
|
73
|
-
it
|
72
|
+
it 'should not throw an error if one of the entries has published date of nil' do # rubocop:disable Metrics/LineLength
|
74
73
|
feed = Feedjira::Parser::Atom.new
|
75
74
|
entry = Feedjira::Parser::AtomEntry.new
|
76
75
|
entry.published = Time.now.to_s
|
@@ -80,122 +79,125 @@ describe Feedjira::FeedUtilities do
|
|
80
79
|
end
|
81
80
|
end
|
82
81
|
|
83
|
-
describe
|
84
|
-
describe
|
82
|
+
describe '#update_from_feed' do
|
83
|
+
describe 'updating feed attributes' do
|
85
84
|
before(:each) do
|
86
|
-
# I'm using the Atom class when I know I should be using a different
|
87
|
-
# method would only be called
|
85
|
+
# I'm using the Atom class when I know I should be using a different
|
86
|
+
# one. However, this update_from_feed method would only be called
|
87
|
+
# against a feed item.
|
88
88
|
@feed = Feedjira::Parser::Atom.new
|
89
|
-
@feed.title =
|
90
|
-
@feed.url =
|
91
|
-
@feed.feed_url =
|
89
|
+
@feed.title = 'A title'
|
90
|
+
@feed.url = 'http://pauldix.net'
|
91
|
+
@feed.feed_url = 'http://feeds.feedburner.com/PaulDixExplainsNothing'
|
92
92
|
@feed.updated = false
|
93
93
|
@updated_feed = @feed.dup
|
94
94
|
end
|
95
95
|
|
96
|
-
it
|
97
|
-
@updated_feed.title =
|
96
|
+
it 'should update the title if changed' do
|
97
|
+
@updated_feed.title = 'new title'
|
98
98
|
@feed.update_from_feed(@updated_feed)
|
99
99
|
expect(@feed.title).to eq @updated_feed.title
|
100
100
|
expect(@feed).to be_updated
|
101
101
|
end
|
102
102
|
|
103
|
-
it
|
103
|
+
it 'should not update the title if the same' do
|
104
104
|
@feed.update_from_feed(@updated_feed)
|
105
105
|
expect(@feed).to_not be_updated
|
106
106
|
end
|
107
107
|
|
108
|
-
it
|
109
|
-
@updated_feed.feed_url =
|
108
|
+
it 'should update the feed_url if changed' do
|
109
|
+
@updated_feed.feed_url = 'a new feed url'
|
110
110
|
@feed.update_from_feed(@updated_feed)
|
111
111
|
expect(@feed.feed_url).to eq @updated_feed.feed_url
|
112
112
|
expect(@feed).to be_updated
|
113
113
|
end
|
114
114
|
|
115
|
-
it
|
115
|
+
it 'should not update the feed_url if the same' do
|
116
116
|
@feed.update_from_feed(@updated_feed)
|
117
117
|
expect(@feed).to_not be_updated
|
118
118
|
end
|
119
119
|
|
120
|
-
it
|
121
|
-
@updated_feed.url =
|
120
|
+
it 'should update the url if changed' do
|
121
|
+
@updated_feed.url = 'a new url'
|
122
122
|
@feed.update_from_feed(@updated_feed)
|
123
123
|
expect(@feed.url).to eq @updated_feed.url
|
124
124
|
end
|
125
125
|
|
126
|
-
it
|
126
|
+
it 'should not update the url if not changed' do
|
127
127
|
@feed.update_from_feed(@updated_feed)
|
128
128
|
expect(@feed).to_not be_updated
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
describe
|
132
|
+
describe 'updating entries' do
|
133
133
|
before(:each) do
|
134
|
-
# I'm using the Atom class when I know I should be using a different
|
135
|
-
# method would only be called
|
134
|
+
# I'm using the Atom class when I know I should be using a different
|
135
|
+
# one. However, this update_from_feed method would only be called
|
136
|
+
# against a feed item.
|
136
137
|
@feed = Feedjira::Parser::Atom.new
|
137
|
-
@feed.title =
|
138
|
-
@feed.url =
|
139
|
-
@feed.feed_url =
|
138
|
+
@feed.title = 'A title'
|
139
|
+
@feed.url = 'http://pauldix.net'
|
140
|
+
@feed.feed_url = 'http://feeds.feedburner.com/PaulDixExplainsNothing'
|
140
141
|
@feed.updated = false
|
141
142
|
@updated_feed = @feed.dup
|
142
143
|
@old_entry = Feedjira::Parser::AtomEntry.new
|
143
|
-
@old_entry.url =
|
144
|
+
@old_entry.url = 'http://pauldix.net/old.html'
|
144
145
|
@old_entry.published = Time.now.to_s
|
145
|
-
@old_entry.entry_id =
|
146
|
+
@old_entry.entry_id = 'entry_id_old'
|
146
147
|
@new_entry = Feedjira::Parser::AtomEntry.new
|
147
|
-
@new_entry.url =
|
148
|
+
@new_entry.url = 'http://pauldix.net/new.html'
|
148
149
|
@new_entry.published = (Time.now + 10).to_s
|
149
|
-
@new_entry.entry_id =
|
150
|
+
@new_entry.entry_id = 'entry_id_new'
|
150
151
|
@feed.entries << @old_entry
|
151
152
|
@updated_feed.entries << @new_entry
|
152
153
|
@updated_feed.entries << @old_entry
|
153
154
|
end
|
154
155
|
|
155
|
-
it
|
156
|
+
it 'should update last-modified from the latest entry date' do
|
156
157
|
@feed.update_from_feed(@updated_feed)
|
157
158
|
expect(@feed.last_modified).to eq @new_entry.published
|
158
159
|
end
|
159
160
|
|
160
|
-
it
|
161
|
+
it 'should put new entries into new_entries' do
|
161
162
|
@feed.update_from_feed(@updated_feed)
|
162
163
|
expect(@feed.new_entries).to eq [@new_entry]
|
163
164
|
end
|
164
165
|
|
165
|
-
it
|
166
|
+
it 'should also put new entries into the entries collection' do
|
166
167
|
@feed.update_from_feed(@updated_feed)
|
167
168
|
expect(@feed.entries).to include(@new_entry)
|
168
169
|
expect(@feed.entries).to include(@old_entry)
|
169
170
|
end
|
170
171
|
end
|
171
172
|
|
172
|
-
describe
|
173
|
+
describe '#update_from_feed' do
|
173
174
|
let(:recent_entry_id) { 'entry_id' }
|
174
175
|
let(:old_entry_id) { nil }
|
175
176
|
|
176
177
|
before(:each) do
|
177
|
-
# I'm using the Atom class when I know I should be using a different
|
178
|
-
# method would only be called
|
178
|
+
# I'm using the Atom class when I know I should be using a different
|
179
|
+
# one. However, this update_from_feed method would only be called
|
180
|
+
# against a feed item.
|
179
181
|
@feed = Feedjira::Parser::Atom.new
|
180
|
-
@feed.title =
|
181
|
-
@feed.url =
|
182
|
-
@feed.feed_url =
|
182
|
+
@feed.title = 'A title'
|
183
|
+
@feed.url = 'http://pauldix.net'
|
184
|
+
@feed.feed_url = 'http://feeds.feedburner.com/PaulDixExplainsNothing'
|
183
185
|
@feed.updated = false
|
184
186
|
@updated_feed = @feed.dup
|
185
187
|
|
186
188
|
@old_entry = Feedjira::Parser::AtomEntry.new
|
187
|
-
@old_entry.url =
|
189
|
+
@old_entry.url = 'http://pauldix.net/old.html'
|
188
190
|
@old_entry.entry_id = old_entry_id
|
189
191
|
@old_entry.published = (Time.now - 10).to_s
|
190
192
|
|
191
193
|
@entry = Feedjira::Parser::AtomEntry.new
|
192
194
|
@entry.published = (Time.now + 10).to_s
|
193
195
|
@entry.entry_id = recent_entry_id
|
194
|
-
@entry.url =
|
196
|
+
@entry.url = 'http://pauldix.net/entry.html'
|
195
197
|
|
196
198
|
# only difference is a changed url
|
197
199
|
@entry_changed_url = @entry.dup
|
198
|
-
@entry_changed_url.url =
|
200
|
+
@entry_changed_url.url = 'http://pauldix.net/updated.html'
|
199
201
|
|
200
202
|
# entry with changed url must be first
|
201
203
|
@feed.entries << @entry
|
@@ -204,8 +206,8 @@ describe Feedjira::FeedUtilities do
|
|
204
206
|
@updated_feed.entries << @old_entry
|
205
207
|
end
|
206
208
|
|
207
|
-
context
|
208
|
-
it
|
209
|
+
context 'changing the url of an existing entry' do
|
210
|
+
it 'should not put the complete feed into new_entries' do
|
209
211
|
@feed.update_from_feed(@updated_feed)
|
210
212
|
expect(@feed.new_entries).to_not include(@entry_changed_url)
|
211
213
|
expect(@feed.new_entries).to_not include(@old_entry)
|
@@ -214,11 +216,11 @@ describe Feedjira::FeedUtilities do
|
|
214
216
|
end
|
215
217
|
end
|
216
218
|
|
217
|
-
context
|
219
|
+
context 'feed not have entry id and only difference is a url' do
|
218
220
|
let(:recent_entry_id) { nil }
|
219
221
|
let(:old_entry_id) { nil }
|
220
222
|
|
221
|
-
it
|
223
|
+
it 'should put the complete feed into new_entries' do
|
222
224
|
@feed.update_from_feed(@updated_feed)
|
223
225
|
expect(@feed.new_entries).to include(@entry_changed_url)
|
224
226
|
expect(@feed.new_entries).to include(@old_entry)
|
@@ -242,7 +244,7 @@ describe Feedjira::FeedUtilities do
|
|
242
244
|
let(:feed_two) { double 'Feed Two', entries: [entry_two] }
|
243
245
|
|
244
246
|
before do
|
245
|
-
stub_const(
|
247
|
+
stub_const('Feedjira::FeedUtilities::UPDATABLE_ATTRIBUTES', [])
|
246
248
|
feed_one.entries << entry_one
|
247
249
|
end
|
248
250
|
|