* Podcasts reachable status #2952 * Specs for podcasts statuses
This commit is contained in:
parent
1923b4230d
commit
d6a151703c
17 changed files with 109 additions and 20 deletions
|
|
@ -47,6 +47,7 @@ Rails/OutputSafety:
|
|||
- 'app/models/message.rb'
|
||||
- 'app/views/api/v0/articles/show.json.jbuilder'
|
||||
- 'app/views/articles/feed.rss.builder'
|
||||
- 'app/views/podcast_episodes/show.html.erb'
|
||||
|
||||
# Offense count: 17
|
||||
# Cop supports --auto-correct.
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ class PodcastEpisodesController < ApplicationController
|
|||
|
||||
def index
|
||||
@podcast_index = true
|
||||
@podcasts = Podcast.order("title asc")
|
||||
@podcast_episodes = PodcastEpisode.includes(:podcast).order("published_at desc").first(20)
|
||||
@podcasts = Podcast.reachable.order("title asc")
|
||||
@podcast_episodes = PodcastEpisode.includes(:podcast).where(podcasts: { reachable: true }).order("published_at desc").first(20)
|
||||
if params[:q].blank?
|
||||
set_surrogate_key_header("podcast_episodes_all " + params[:q].to_s,
|
||||
@podcast_episodes.map { |e| e["record_key"] })
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class StoriesController < ApplicationController
|
|||
elsif (@article = Article.find_by(slug: params[:slug])&.decorate)
|
||||
handle_possible_redirect
|
||||
else
|
||||
@podcast = Podcast.find_by(slug: params[:username]) || not_found
|
||||
@podcast = Podcast.reachable.find_by(slug: params[:username]) || not_found
|
||||
@episode = PodcastEpisode.find_by(slug: params[:slug]) || not_found
|
||||
handle_podcast_show
|
||||
end
|
||||
|
|
@ -64,7 +64,7 @@ class StoriesController < ApplicationController
|
|||
end
|
||||
|
||||
def handle_user_or_organization_or_podcast_or_page_index
|
||||
@podcast = Podcast.find_by(slug: params[:username].downcase)
|
||||
@podcast = Podcast.reachable.find_by(slug: params[:username].downcase)
|
||||
@organization = Organization.find_by(slug: params[:username].downcase)
|
||||
@page = Page.find_by(slug: params[:username].downcase, is_top_level_path: true)
|
||||
if @podcast
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class PodcastDashboard < Administrate::BaseDashboard
|
|||
image: CarrierwaveField,
|
||||
pattern_image: CarrierwaveField,
|
||||
slug: Field::String,
|
||||
reachable: Field::Boolean,
|
||||
status_notice: Field::Text,
|
||||
created_at: Field::DateTime,
|
||||
updated_at: Field::DateTime
|
||||
|
|
@ -36,6 +37,8 @@ class PodcastDashboard < Administrate::BaseDashboard
|
|||
COLLECTION_ATTRIBUTES = %i[
|
||||
podcast_episodes
|
||||
id
|
||||
reachable
|
||||
status_notice
|
||||
title
|
||||
description
|
||||
].freeze
|
||||
|
|
@ -59,6 +62,7 @@ class PodcastDashboard < Administrate::BaseDashboard
|
|||
image
|
||||
pattern_image
|
||||
slug
|
||||
reachable
|
||||
created_at
|
||||
updated_at
|
||||
].freeze
|
||||
|
|
@ -82,6 +86,7 @@ class PodcastDashboard < Administrate::BaseDashboard
|
|||
main_color_hex
|
||||
image
|
||||
slug
|
||||
reachable
|
||||
].freeze
|
||||
|
||||
# Overwrite this method to customize how podcasts are displayed
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ class Podcast < ApplicationRecord
|
|||
|
||||
after_save :bust_cache
|
||||
|
||||
scope :reachable, -> { where(reachable: true) }
|
||||
|
||||
alias_attribute :path, :slug
|
||||
alias_attribute :profile_image_url, :image_url
|
||||
alias_attribute :name, :title
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ module Podcasts
|
|||
rescue StandardError
|
||||
# podcast episode must have a media_url
|
||||
episode.media_url = item.enclosure.url
|
||||
episode.podcast.update(status_notice: "This podcast may not be playable in the browser") if episode.podcast.status_notice.empty?
|
||||
episode.podcast.update(status_notice: I18n.t(:unplayable, scope: "podcasts.statuses")) if episode.podcast.status_notice.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,13 +6,25 @@ module Podcasts
|
|||
def get_episodes(podcast, num = 1000)
|
||||
rss = HTTParty.get(podcast.feed_url).body
|
||||
feed = RSS::Parser.parse(rss, false)
|
||||
|
||||
set_unreachable(podcast, :unparsable) && return unless feed
|
||||
|
||||
get_episode = Podcasts::GetEpisode.new(podcast)
|
||||
feed.items.first(num).each do |item|
|
||||
get_episode.call(item)
|
||||
end
|
||||
podcast.update_columns(reachable: true, status_notice: "")
|
||||
feed.items.size
|
||||
rescue StandardError => e
|
||||
Rails.logger.error(e)
|
||||
rescue Net::OpenTimeout, Errno::ECONNREFUSED => _e
|
||||
set_unreachable(podcast, :unreachable)
|
||||
rescue RSS::NotWellFormedError => _e
|
||||
set_unreachable(podcast, :unparsable)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_unreachable(podcast, status = :unreachable)
|
||||
podcast.update_columns(reachable: false, status_notice: I18n.t(status, scope: "podcasts.statuses"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if !@episode.podcast.status_notice.empty? %>
|
||||
<%# temp, until podcast_episode statuses are introduced %>
|
||||
<% if @episode.podcast.status_notice.to_s.include?("may not be playable") %>
|
||||
<center>
|
||||
<h1 style="color: #e05252;">
|
||||
<%= @episode.podcast.status_notice %>
|
||||
|
|
|
|||
|
|
@ -45,3 +45,8 @@ en:
|
|||
administrate:
|
||||
actions:
|
||||
new: 'New'
|
||||
podcasts:
|
||||
statuses:
|
||||
unreachable: Podcast's feed_url is not reachable
|
||||
unparsable: Podcast's rss couldn't be parsed
|
||||
unplayable: This podcast may not be playable in the browser
|
||||
|
|
|
|||
5
db/migrate/20190628123548_add_reachable_to_podcasts.rb
Normal file
5
db/migrate/20190628123548_add_reachable_to_podcasts.rb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class AddReachableToPodcasts < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :podcasts, :reachable, :boolean, default: true
|
||||
end
|
||||
end
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2019_06_26_022355) do
|
||||
ActiveRecord::Schema.define(version: 2019_06_28_123548) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
|
|
@ -667,6 +667,7 @@ ActiveRecord::Schema.define(version: 2019_06_26_022355) do
|
|||
t.string "main_color_hex", null: false
|
||||
t.string "overcast_url"
|
||||
t.string "pattern_image"
|
||||
t.boolean "reachable", default: true
|
||||
t.string "slug", null: false
|
||||
t.string "soundcloud_url"
|
||||
t.text "status_notice", default: ""
|
||||
|
|
|
|||
19
spec/requests/podcasts/podcast_show_spec.rb
Normal file
19
spec/requests/podcasts/podcast_show_spec.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe "PodcastShow", type: :request do
|
||||
describe "GET podcast show" do
|
||||
it "renders 404 for an unreachable podcast" do
|
||||
podcast = create(:podcast, reachable: false)
|
||||
expect do
|
||||
get "/#{podcast.slug}"
|
||||
end.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
||||
it "renders ok" do
|
||||
podcast = create(:podcast)
|
||||
create(:podcast_episode, podcast: podcast)
|
||||
get "/#{podcast.slug}"
|
||||
expect(response).to have_http_status(:ok)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -13,6 +13,27 @@ RSpec.describe Podcasts::Feed, vcr: vcr_option do
|
|||
podcast
|
||||
end
|
||||
|
||||
context "when unreachable" do
|
||||
let(:un_feed_url) { "http://podcast.example.com/podcast" }
|
||||
let(:unpodcast) { create(:podcast, feed_url: un_feed_url) }
|
||||
|
||||
it "sets reachable and status" do
|
||||
stub_request(:get, "http://podcast.example.com/podcast").to_return(status: 200, body: "blah")
|
||||
described_class.new.get_episodes(unpodcast, 2)
|
||||
unpodcast.reload
|
||||
expect(unpodcast.reachable).to be false
|
||||
expect(unpodcast.status_notice).to include("rss couldn't be parsed")
|
||||
end
|
||||
|
||||
it "sets reachable" do
|
||||
allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast").and_raise(Errno::ECONNREFUSED)
|
||||
described_class.new.get_episodes(unpodcast, 2)
|
||||
unpodcast.reload
|
||||
expect(unpodcast.reachable).to be false
|
||||
expect(unpodcast.status_notice).to include("is not reachable")
|
||||
end
|
||||
end
|
||||
|
||||
context "when creating" do
|
||||
before do
|
||||
stub_request(:head, "https://traffic.libsyn.com/sedaily/AnalyseAsia.mp3").to_return(status: 200)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,26 @@ RSpec.describe "User visits podcast show page", type: :system do
|
|||
expect(find("#comment_commentable_id", visible: false).value).to eq(podcast_episode.id.to_s)
|
||||
end
|
||||
|
||||
context "when podcast has a status_notice" do
|
||||
let(:podcast) { create(:podcast, status_notice: "This podcast may not be playable in the browser") }
|
||||
let!(:podcast_episode) { create(:podcast_episode, podcast_id: podcast.id) }
|
||||
|
||||
it "displays the status_notice" do
|
||||
visit podcast_episode.path.to_s
|
||||
expect(page).to have_text(podcast.status_notice)
|
||||
end
|
||||
end
|
||||
|
||||
context "when podcast has another status_notice (just in case)" do
|
||||
let(:podcast) { create(:podcast, status_notice: "Random status notice") }
|
||||
let!(:podcast_episode) { create(:podcast_episode, podcast_id: podcast.id) }
|
||||
|
||||
it "doesn't display status_notice" do
|
||||
visit podcast_episode.path.to_s
|
||||
expect(page).not_to have_text("Random status notice")
|
||||
end
|
||||
end
|
||||
|
||||
context "when there're existing comments" do
|
||||
let(:user) { create(:user) }
|
||||
let(:comment) { create(:comment, user_id: user.id, commentable: podcast_episode) }
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
# require 'rails_helper'
|
||||
#
|
||||
# feature 'User visits podcast index page' do
|
||||
# scenario 'they see the foobar on the page' do
|
||||
# visit "/pod"
|
||||
#
|
||||
# fill_in 'Name', with: 'My foobar'
|
||||
# click_button 'Create Foobar'
|
||||
# expect(page).to have_css '.foobar-name', 'My foobar'
|
||||
# end
|
||||
# end
|
||||
|
|
@ -3,6 +3,8 @@ require "rails_helper"
|
|||
RSpec.describe "User visits /pod page", type: :system do
|
||||
let!(:podcast_episode) { create(:podcast_episode) }
|
||||
let!(:podcast_episode2) { create(:podcast_episode) }
|
||||
let(:podcast) { create(:podcast, reachable: false) }
|
||||
let!(:un_podcast_episode) { create(:podcast_episode, podcast: podcast) }
|
||||
|
||||
before { visit "/pod" }
|
||||
|
||||
|
|
@ -12,4 +14,10 @@ RSpec.describe "User visits /pod page", type: :system do
|
|||
expect(page).to have_link(nil, href: podcast_episode2.path)
|
||||
end
|
||||
end
|
||||
|
||||
it "doesn't display an unreachable podcast" do
|
||||
within "#articles-list" do
|
||||
expect(page).not_to have_link(nil, href: un_podcast_episode.path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue