Skip to content

Commit bf252d2

Browse files
authored
Fallback experience when Medium's RSS-to-JSON proxy is rate-limiting / throwing 429s (#2478)
1 parent da98407 commit bf252d2

3 files changed

Lines changed: 57 additions & 5 deletions

File tree

app/services/medium.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
class Medium
77
def posts
8-
content_hash['items']
8+
content_hash['items'] || []
9+
rescue OpenURI::HTTPError, SocketError, JSON::ParserError
10+
[]
911
end
1012

1113
private

spec/requests/pages_spec.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
let(:user) { create(:user) }
55

66
describe "#home" do
7+
let(:medium_posts) do
8+
[{ 'title' => 'Test Post', 'link' => 'https://medium.com/ifme/test', 'author' => 'Test Author' }]
9+
end
10+
11+
before do
12+
allow_any_instance_of(Medium).to receive(:posts).and_return(medium_posts)
13+
end
14+
715
it "respond to request" do
816
get pages_home_path
917
expect(response).to be_successful
@@ -40,7 +48,7 @@
4048
it "has blurbs and posts" do
4149
get pages_home_path
4250

43-
expect(assigns(:posts)[0].keys).to contain_exactly(:link, :link_name, :author)
51+
expect(assigns(:posts).first.keys).to contain_exactly(:link, :link_name, :author)
4452
blurbs_file = File.read("doc/pages/blurbs.json")
4553
expect(assigns(:blurbs)).to eq(JSON.parse(blurbs_file))
4654
end

spec/services/medium_spec.rb

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,50 @@
33
describe Medium do
44
subject { Medium.new.posts }
55

6-
it 'retrieve Medium posts from API' do
7-
expect(subject.first['title']).to be_truthy
8-
expect(subject.first['link']).to be_truthy
6+
context 'when the API is available' do
7+
let(:response_json) do
8+
{ 'items' => [{ 'title' => 'Test Post', 'link' => 'https://medium.com/ifme/test', 'author' => 'Test Author' }] }.to_json
9+
end
10+
11+
before do
12+
allow(URI).to receive(:open).and_yield(StringIO.new(response_json))
13+
end
14+
15+
it 'returns posts with title and link' do
16+
expect(subject.first['title']).to be_truthy
17+
expect(subject.first['link']).to be_truthy
18+
end
19+
end
20+
21+
context 'when the API returns a 429 Too Many Requests error' do
22+
before do
23+
allow(URI).to receive(:open).and_raise(
24+
OpenURI::HTTPError.new('429 Too Many Requests', StringIO.new)
25+
)
26+
end
27+
28+
it 'returns an empty array' do
29+
expect(subject).to eq([])
30+
end
31+
end
32+
33+
context 'when a network error occurs' do
34+
before do
35+
allow(URI).to receive(:open).and_raise(SocketError)
36+
end
37+
38+
it 'returns an empty array' do
39+
expect(subject).to eq([])
40+
end
41+
end
42+
43+
context 'when the response is not valid JSON' do
44+
before do
45+
allow(URI).to receive(:open).and_yield(StringIO.new('not valid json'))
46+
end
47+
48+
it 'returns an empty array' do
49+
expect(subject).to eq([])
50+
end
951
end
1052
end

0 commit comments

Comments
 (0)