docbrown/spec/models/podcast_spec.rb
Mac Siri 842e6880b8
Routine rubocop fix on /spec (#19217)
* Softrun rubocop

* Hardrun rubocop (-A)

* Change a rubocop rule

* Add missing cops

* Undo & redo rubocop -A
2023-03-21 09:55:26 -04:00

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