* Softrun rubocop * Hardrun rubocop (-A) * Change a rubocop rule * Add missing cops * Undo & redo rubocop -A
208 lines
7.2 KiB
Ruby
208 lines
7.2 KiB
Ruby
require "rails_helper"
|
|
|
|
RSpec.describe Podcast do
|
|
let(:podcast) { create(:podcast) }
|
|
|
|
it "has a creator" do
|
|
user = build(:user)
|
|
pod = create(:podcast, creator: user)
|
|
expect(pod.creator).to eq(user)
|
|
end
|
|
|
|
context "when callbacks are triggered after save" do
|
|
it "triggers cache busting on save" do
|
|
sidekiq_assert_enqueued_with(job: Podcasts::BustCacheWorker, args: [podcast.path]) do
|
|
podcast.save
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "validations" do
|
|
describe "builtin validations" do
|
|
subject { podcast }
|
|
|
|
it { is_expected.to belong_to(:creator).class_name("User").inverse_of(:created_podcasts).optional }
|
|
|
|
it { is_expected.to have_many(:owners).through(:podcast_ownerships) }
|
|
it { is_expected.to have_many(:podcast_episodes).dependent(:destroy) }
|
|
it { is_expected.to have_many(:podcast_ownerships).dependent(:destroy) }
|
|
|
|
it { is_expected.to validate_presence_of(:feed_url) }
|
|
it { is_expected.to validate_presence_of(:image) }
|
|
it { is_expected.to validate_presence_of(:main_color_hex) }
|
|
it { is_expected.to validate_presence_of(:slug) }
|
|
it { is_expected.to validate_presence_of(:title) }
|
|
end
|
|
|
|
# Couldn't use shoulda uniqueness matchers for these tests because:
|
|
# Shoulda uses `save(validate: false)` which skips validations
|
|
# So an invalid record is trying to be saved but fails because of the db constraints
|
|
# https://github.com/thoughtbot/shoulda-matchers/blob/9f0def1/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb#L549-L552
|
|
|
|
it "validates slug uniqueness" do
|
|
podcast2 = build(:podcast, slug: podcast.slug)
|
|
|
|
expect(podcast2).not_to be_valid
|
|
expect(podcast2.errors[:slug]).to be_present
|
|
end
|
|
|
|
it "validates feed_url uniqueness" do
|
|
podcast2 = build(:podcast, feed_url: podcast.feed_url)
|
|
|
|
expect(podcast2).not_to be_valid
|
|
expect(podcast2.errors[:feed_url]).to be_present
|
|
end
|
|
|
|
it "validates feed_url format" do
|
|
podcast2 = build(:podcast, feed_url: "example.com")
|
|
|
|
expect(podcast2).not_to be_valid
|
|
expect(podcast2.errors[:feed_url]).to be_present
|
|
end
|
|
|
|
it "validates main_color_hex" do
|
|
podcast2 = build(:podcast, main_color_hex: "#FFFFFF")
|
|
|
|
expect(podcast2).not_to be_valid
|
|
expect(podcast2.errors[:main_color_hex]).to be_present
|
|
end
|
|
|
|
it "doesn't allow to create a podcast with a reserved word slug" do
|
|
enter_podcast = build(:podcast, slug: "enter")
|
|
expect(enter_podcast).not_to be_valid
|
|
expect(enter_podcast.errors[:slug]).to be_present
|
|
end
|
|
|
|
it "is invalid when a user with a username equal to the podcast slug exists" do
|
|
create(:user, username: "annabu")
|
|
user_podcast = build(:podcast, slug: "annabu")
|
|
expect(user_podcast).not_to be_valid
|
|
expect(user_podcast.errors[:slug]).to be_present
|
|
end
|
|
|
|
it "is invalid when a page with a slug equal to the podcast slug exists" do
|
|
create(:page, slug: "superpage")
|
|
user_podcast = build(:podcast, slug: "superpage")
|
|
expect(user_podcast).not_to be_valid
|
|
expect(user_podcast.errors[:slug]).to be_present
|
|
end
|
|
|
|
it "is invalid when an org with a slug equal to the podcast slug exists" do
|
|
create(:organization, slug: "superorganization")
|
|
user_podcast = build(:podcast, slug: "superorganization")
|
|
expect(user_podcast).not_to be_valid
|
|
expect(user_podcast.errors[:slug]).to be_present
|
|
end
|
|
end
|
|
|
|
describe ".reachable" do
|
|
it "is reachable when it has a reachable episode" do
|
|
expect do
|
|
create(:podcast_episode, reachable: true)
|
|
create(:podcast, published: true)
|
|
end.to change(described_class.reachable, :count).by(1)
|
|
end
|
|
|
|
it "is reachable when it has a reachable episode even if it is unpublished" do
|
|
expect do
|
|
create(:podcast_episode, reachable: true)
|
|
create(:podcast, published: false)
|
|
end.to change(described_class.reachable, :count).by(1)
|
|
end
|
|
|
|
it "is not reachable when it has an unreachable episode" do
|
|
expect do
|
|
create(:podcast_episode, reachable: false)
|
|
create(:podcast, published: true)
|
|
end.not_to change(described_class.reachable, :count)
|
|
end
|
|
end
|
|
|
|
describe ".available" do
|
|
it "is available when it has a reachable episode and it is published" do
|
|
expect do
|
|
create(:podcast_episode, reachable: true)
|
|
create(:podcast, published: true)
|
|
end.to change(described_class.available, :count).by(1)
|
|
end
|
|
|
|
it "is not available when it has an unreachable episode" do
|
|
expect do
|
|
create(:podcast_episode, reachable: false)
|
|
create(:podcast, published: true)
|
|
end.not_to change(described_class.available, :count)
|
|
end
|
|
|
|
it "is not available when it is not published" do
|
|
expect do
|
|
create(:podcast, published: false)
|
|
end.not_to change(described_class.available, :count)
|
|
end
|
|
end
|
|
|
|
describe "#existing_episode" do
|
|
let(:guid) { "<guid isPermaLink=\"false\">http://podcast.example/file.mp3</guid>" }
|
|
let(:item_attributes) do
|
|
{
|
|
pubDate: "2019-06-19",
|
|
enclosure_url: "https://audio.simplecast.com/2330f132.mp3",
|
|
description: "yet another podcast",
|
|
title: "lightalloy's podcast",
|
|
guid: guid,
|
|
itunes_subtitle: "hello",
|
|
content_encoded: nil,
|
|
itunes_summary: "world"
|
|
}
|
|
end
|
|
let(:item) do
|
|
build(:podcast_episode_rss_item, item_attributes.merge(link: "https://litealloy.ru"))
|
|
end
|
|
|
|
it "determines existing episode by media_url" do
|
|
episode = create(:podcast_episode, podcast: podcast, media_url: "https://audio.simplecast.com/2330f132.mp3")
|
|
expect(podcast.existing_episode(item)).to eq(episode)
|
|
end
|
|
|
|
it "determines existing episode by title" do
|
|
episode = create(:podcast_episode, podcast: podcast, title: "lightalloy's podcast")
|
|
expect(podcast.existing_episode(item)).to eq(episode)
|
|
end
|
|
|
|
it "determines existing episode by guid" do
|
|
episode = create(:podcast_episode, podcast: podcast, guid: guid)
|
|
expect(podcast.existing_episode(item)).to eq(episode)
|
|
end
|
|
|
|
it "determines existing episode by website_url" do
|
|
episode = create(:podcast_episode, podcast: podcast, website_url: "https://litealloy.ru")
|
|
expect(podcast.existing_episode(item)).to eq(episode)
|
|
end
|
|
|
|
it "doesn't determine existing episode if episode link is empty" do
|
|
create(:podcast_episode, podcast: podcast, website_url: "")
|
|
no_link_item = build(:podcast_episode_rss_item, item_attributes.merge(link: ""))
|
|
expect(podcast.existing_episode(no_link_item)).to be_nil
|
|
end
|
|
|
|
it "doesn't determine existing episode by non-unique website_url" do
|
|
podcast.update_attribute(:unique_website_url?, false)
|
|
create(:podcast_episode, podcast: podcast, website_url: "https://litealloy.ru")
|
|
expect(podcast.existing_episode(item)).to be_nil
|
|
end
|
|
end
|
|
|
|
describe "#admins" do
|
|
let(:user) { create(:user) }
|
|
|
|
it "returns podcast admins" do
|
|
user.add_role(:podcast_admin, podcast)
|
|
expect(podcast.admins).to include(user)
|
|
end
|
|
|
|
it "does not return admins for other podcasts" do
|
|
other_podcast = create(:podcast)
|
|
user.add_role(:podcast_admin, other_podcast)
|
|
expect(podcast.admins).to be_empty
|
|
end
|
|
end
|
|
end
|