Creating podcasts by users (#3730) [deploy]
* Create podcast as a user [WIP] * Sample css for podcast form * Nicer podcasts suggesting form * Validate podcast feed_url * Validate podcast main_color_hex * Fix podcasts specs * Fix form appearance * Placeholder for podcast main_color_hex * Provide a link to suggest a podcast * Add a checkbox and a role for when a podcast is added by an owner * Prettier checkbox in the podcasts form * Added creator to podcasts * Set the podcast creator * Fix the /pod spec * Added creator information to the internal podcast page * Added cta class to the podcasts submit button * Global notice when a podcast was suggested Co-authored-by: Ben Halpern <bendhalpern@gmail.com>
This commit is contained in:
parent
482a77a375
commit
e09e46ec99
21 changed files with 359 additions and 58 deletions
|
|
@ -1227,6 +1227,11 @@
|
|||
);
|
||||
}
|
||||
}
|
||||
.suggest-podcast {
|
||||
color: var(--theme-secondary-color, #666666);
|
||||
text-decoration: underline;
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
hr {
|
||||
opacity: 0.2;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
@import 'settings';
|
||||
@import 'signin';
|
||||
@import 'podcast-episodes-show';
|
||||
@import 'podcast-form';
|
||||
@import 'more-articles';
|
||||
@import 'user-profile-header';
|
||||
@import 'comments';
|
||||
|
|
|
|||
98
app/assets/stylesheets/podcast-form.scss
Normal file
98
app/assets/stylesheets/podcast-form.scss
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
@import 'variables';
|
||||
|
||||
#page-content.podcasts-new, #page-content.podcasts-create {
|
||||
.podcasts-form {
|
||||
text-align: left;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); //Invisible black
|
||||
max-width: 750px;
|
||||
padding-bottom: 30px;
|
||||
@media screen and (min-width: 750px) {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
@media screen and (min-width: 950px) {
|
||||
width: 100%;
|
||||
margin-left: 2.3%;
|
||||
margin-right: 15px;
|
||||
max-width: calc(100% - 380px);
|
||||
float: left;
|
||||
}
|
||||
@media screen and (min-width: 1120px) {
|
||||
max-width: calc(100% - 640px);
|
||||
}
|
||||
@media screen and (min-width: 1240px) {
|
||||
width: 100%;
|
||||
margin-left: 2.3%;
|
||||
margin-right: 15px;
|
||||
max-width: 604px;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.45em;
|
||||
}
|
||||
.podcast-errors {
|
||||
background: $red;
|
||||
color: $black;
|
||||
padding: 20px;
|
||||
border-radius: 3px;
|
||||
h2 {
|
||||
color: $black;
|
||||
margin: 0;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
form {
|
||||
font-size: 15px;
|
||||
input[type='checkbox']{
|
||||
display: inline
|
||||
}
|
||||
input:not([type='checkbox']) {
|
||||
width: 650px;
|
||||
max-width: calc(100% - 30px);
|
||||
padding: 12px;
|
||||
font-size: 19px;
|
||||
border: 1px solid rgb(222, 230, 233);
|
||||
border-radius: 3px;
|
||||
&[type='file'] {
|
||||
border: 0px;
|
||||
padding: 12px 0px;
|
||||
}
|
||||
&[type='submit'] {
|
||||
width: 255px;
|
||||
max-width: 100%;
|
||||
padding: 14px 0px;
|
||||
margin-top: 20px;
|
||||
font-size: 1.5em;
|
||||
cursor: pointer;
|
||||
&.danger-button {
|
||||
background: $red;
|
||||
}
|
||||
&:hover {
|
||||
opacity: 0.88;
|
||||
}
|
||||
}
|
||||
}
|
||||
textarea {
|
||||
width: 650px;
|
||||
max-width: calc(100% - 30px);
|
||||
padding: 12px;
|
||||
font-size: 19px;
|
||||
border: 1px solid rgb(222, 230, 233);
|
||||
border-radius: 3px;
|
||||
}
|
||||
label {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 14px 0px 8px;
|
||||
}
|
||||
label.i_am_owner {
|
||||
padding: 2px 0 2px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -64,6 +64,8 @@ body {
|
|||
&.notifications-index,
|
||||
&.stories-search,
|
||||
&.podcast_episodes-index,
|
||||
&.podcasts-new,
|
||||
&.podcasts-create,
|
||||
&.reading_list_items-index,
|
||||
&.history-index,
|
||||
.tags-index,
|
||||
|
|
|
|||
34
app/controllers/podcasts_controller.rb
Normal file
34
app/controllers/podcasts_controller.rb
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
class PodcastsController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
|
||||
def new
|
||||
@podcast = Podcast.new
|
||||
@podcasts = Podcast.available.order("title asc")
|
||||
@podcast_index = true
|
||||
end
|
||||
|
||||
def create
|
||||
@podcast = Podcast.new(podcast_params)
|
||||
@podcast.creator = current_user
|
||||
if @podcast.save
|
||||
current_user.add_role(:podcast_admin, @podcast) if added_by_owner?
|
||||
flash[:global_notice] = "Podcast suggested"
|
||||
redirect_to "/pod"
|
||||
else
|
||||
@podcasts = Podcast.available.order("title asc")
|
||||
@podcast_index = true
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def added_by_owner?
|
||||
params[:i_am_owner].to_i == 1
|
||||
end
|
||||
|
||||
def podcast_params
|
||||
allowed_params = %i[android_url image itunes_url main_color_hex overcast_url pattern_image slug soundcloud_url twitter_username website_url title feed_url description]
|
||||
params.require(:podcast).permit(allowed_params)
|
||||
end
|
||||
end
|
||||
|
|
@ -2,12 +2,14 @@ class Podcast < ApplicationRecord
|
|||
resourcify
|
||||
|
||||
has_many :podcast_episodes
|
||||
belongs_to :creator, class_name: "User", inverse_of: :created_podcasts, foreign_key: :creator_id, optional: true
|
||||
|
||||
mount_uploader :image, ProfileImageUploader
|
||||
mount_uploader :pattern_image, ProfileImageUploader
|
||||
|
||||
validates :main_color_hex, :title, :feed_url, :image, presence: true
|
||||
validates :feed_url, uniqueness: true
|
||||
validates :main_color_hex, format: /\A([a-fA-F]|[0-9]){6}\Z/
|
||||
validates :feed_url, uniqueness: true, url: { schemes: %w[https http] }
|
||||
validates :slug,
|
||||
presence: true,
|
||||
uniqueness: true,
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ class User < ApplicationRecord
|
|||
has_many :webhook_endpoints, class_name: "Webhook::Endpoint", foreign_key: :user_id, inverse_of: :user, dependent: :delete_all
|
||||
has_many :user_blocks
|
||||
has_one :pro_membership, dependent: :destroy
|
||||
has_many :created_podcasts, class_name: "Podcast", foreign_key: :creator_id, inverse_of: :creator, dependent: :nullify
|
||||
|
||||
mount_uploader :profile_image, ProfileImageUploader
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@
|
|||
<p>There are no admins for this podcast.</p>
|
||||
<% end %>
|
||||
|
||||
<% if @podcast.creator.present? %>
|
||||
<p>Created by <%= link_to "@#{@podcast.creator.username}", "/#{@podcast.creator.username}" %></p>
|
||||
<% end %>
|
||||
|
||||
<%= form_for @podcast, url: add_admin_internal_podcast_path(@podcast.id), html: { method: :post } do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label "Add Admin (by user_id)", for: "podcast_user_id" %>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% if @podcast %>
|
||||
<% if @podcast && @podcast.persisted? %>
|
||||
<% title @podcast.title + " — The Practical Dev" %>
|
||||
|
||||
<%= content_for :page_meta do %>
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@
|
|||
</div>
|
||||
</a>
|
||||
<% end %>
|
||||
<p>If you know of a great dev podcast that should be added to this list, contact <a href="mailto:<%= SiteConfig.default_site_email %>"><%= SiteConfig.default_site_email %></a></p>
|
||||
</div>
|
||||
<p><%= link_to "Suggest a Podcast", new_podcast_path, class: "suggest-podcast" %></p>
|
||||
</div>
|
||||
</div>
|
||||
<% elsif @podcast %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
<% title @podcast.title + " — The Practical Dev" %>
|
||||
|
||||
<%= content_for :page_meta do %>
|
||||
<link rel="canonical" href="https://dev.to/<%= @podcast.slug %>" />
|
||||
<meta name="description" content="Software Engineering Daily is a programming podcast that airs five days a week.">
|
||||
<meta name="keywords" content="software development,engineering,rails,javascript,ruby">
|
||||
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="https://dev.to/<%= @podcast.slug %>" />
|
||||
<meta property="og:title" content="Software Engineering Daily — The Practical Dev" />
|
||||
<meta property="og:image" content="https://res.cloudinary.com/practicaldev/image/fetch/c_scale,h_180,w_180,r_max/u_devuserbg_npatyr,y_60/<%= cloudinary(@podcast.image_url, 180) %>">
|
||||
|
||||
<meta property="og:description" content="Software Engineering Daily is a programming podcast that airs five days a week" />
|
||||
<meta property="og:site_name" content="The Practical Dev" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:site" content="@ThePracticalDev">
|
||||
<meta name="twitter:creator" content="@software_daily">
|
||||
<meta name="twitter:title" content="Software Engineering Daily — The Practical Dev">
|
||||
<meta name="twitter:description" content="Software Engineering Daily is a programming podcast that airs five days a week." />
|
||||
<meta name="twitter:image:src" content="https://res.cloudinary.com/practicaldev/image/fetch/c_scale,h_180,w_180,r_max/u_devuserbg_npatyr,y_60/<%= cloudinary(@podcast.image_url, 180) %>">
|
||||
<% end %>
|
||||
|
||||
<div class="podcast-index-container">
|
||||
<div class="episodes-container">
|
||||
<% @podcast_episodes.each do |episode| %>
|
||||
<a href="<%= episode.path %>/edit">
|
||||
<div class="individual-episode">
|
||||
<div class="pic">
|
||||
<%= cl_image_tag(episode.image_url || @podcast.image_url,
|
||||
type: "fetch",
|
||||
crop: "fill",
|
||||
width: 420,
|
||||
height: 420,
|
||||
quality: "auto",
|
||||
flags: "progressive",
|
||||
fetch_format: "auto",
|
||||
sign_url: true,
|
||||
alt: episode.title) %>
|
||||
</div>
|
||||
<div class="title">
|
||||
<%= episode.title %>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<% end %>
|
||||
<div class="pagination-wrapper">
|
||||
<%= paginate @podcast_episodes %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
78
app/views/podcasts/_form.html.erb
Normal file
78
app/views/podcasts/_form.html.erb
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<%= form_with(model: podcast, local: true) do |form| %>
|
||||
<div>
|
||||
<header>
|
||||
<a href="/pod" class="podcast-back-button">< return to podcasts</a>
|
||||
<h2>Suggest a Podcast</h2>
|
||||
</header>
|
||||
<% if podcast.errors.any? %>
|
||||
<div class="podcast-errors">
|
||||
<h2><%= pluralize(podcast.errors.count, "error") %> while creating a podcast:</h2>
|
||||
<ul>
|
||||
<% podcast.errors.full_messages.each do |message| %>
|
||||
<li><%= message %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
<div id="podcast-form-data">
|
||||
<div class="field">
|
||||
<%= check_box_tag :i_am_owner %><%= label_tag :i_am_owner, "I am the owner of this podcast", class: "i_am_owner" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :title %>
|
||||
<%= form.text_field :title, placeholder: "" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :description, "Description" %>
|
||||
<%= form.text_area :description, placeholder: "" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :website_url %>
|
||||
<%= form.text_field :website_url %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :feed_url %>
|
||||
<%= form.text_field :feed_url %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :twitter_username %>
|
||||
<%= form.text_field :twitter_username %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :slug %>
|
||||
<%= form.text_field :slug %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :main_color_hex %>
|
||||
<%= form.text_field :main_color_hex, placeholder: "FF00FF" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :image %>
|
||||
<%= form.file_field :image %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :pattern_image %>
|
||||
<%= form.file_field :pattern_image %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :android_url %>
|
||||
<%= form.text_field :android_url %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :itunes_url %>
|
||||
<%= form.text_field :itunes_url %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :overcast_url %>
|
||||
<%= form.text_field :overcast_url %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.label :soundcloud_url %>
|
||||
<%= form.text_field :soundcloud_url %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= form.submit "Suggest", class: "cta" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
13
app/views/podcasts/new.html.erb
Normal file
13
app/views/podcasts/new.html.erb
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<%= content_for :page_meta do %>
|
||||
<%= render "podcast_episodes/meta" %>
|
||||
<% end %>
|
||||
<div class="home">
|
||||
<%= render "podcast_episodes/sidebar" %>
|
||||
<div class="podcasts-form" id="podcasts-form">
|
||||
<%= render "form", podcast: @podcast %>
|
||||
</div>
|
||||
<%= render "podcast_episodes/sidebar_additional" %>
|
||||
</div>
|
||||
|
||||
<%= render "stories/narrow_nav_menu" %>
|
||||
<%= render "stories/stories_list_script" %>
|
||||
|
|
@ -201,6 +201,7 @@ Rails.application.routes.draw do
|
|||
resources :badges, only: [:index]
|
||||
resource :pro_membership, path: :pro, only: %i[show create update]
|
||||
resources :user_blocks, param: :blocked_id, only: %i[show create destroy]
|
||||
resources :podcasts, only: %i[new create]
|
||||
resolve("ProMembership") { [:pro_membership] } # see https://guides.rubyonrails.org/routing.html#using-resolve
|
||||
|
||||
get "/chat_channel_memberships/find_by_chat_channel_id" => "chat_channel_memberships#find_by_chat_channel_id"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
class AddCreateByUserIdToPodcasts < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :podcasts, :creator_id, :integer
|
||||
add_index :podcasts, :creator_id
|
||||
add_foreign_key :podcasts, :users, column: :creator_id, null: true
|
||||
end
|
||||
end
|
||||
|
|
@ -11,7 +11,6 @@
|
|||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2019_12_27_114543) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
|
|
@ -750,6 +749,7 @@ ActiveRecord::Schema.define(version: 2019_12_27_114543) do
|
|||
create_table "podcasts", id: :serial, force: :cascade do |t|
|
||||
t.string "android_url"
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "creator_id"
|
||||
t.text "description"
|
||||
t.string "feed_url", null: false
|
||||
t.string "image", null: false
|
||||
|
|
@ -767,6 +767,7 @@ ActiveRecord::Schema.define(version: 2019_12_27_114543) do
|
|||
t.boolean "unique_website_url?", default: true
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "website_url"
|
||||
t.index ["creator_id"], name: "index_podcasts_on_creator_id"
|
||||
t.index ["feed_url"], name: "index_podcasts_on_feed_url", unique: true
|
||||
t.index ["slug"], name: "index_podcasts_on_slug", unique: true
|
||||
end
|
||||
|
|
@ -1202,6 +1203,7 @@ ActiveRecord::Schema.define(version: 2019_12_27_114543) do
|
|||
add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id"
|
||||
add_foreign_key "oauth_access_tokens", "users", column: "resource_owner_id"
|
||||
add_foreign_key "page_views", "articles", on_delete: :cascade
|
||||
add_foreign_key "podcasts", "users", column: "creator_id"
|
||||
add_foreign_key "sponsorships", "organizations"
|
||||
add_foreign_key "sponsorships", "users"
|
||||
add_foreign_key "tag_adjustments", "articles", on_delete: :cascade
|
||||
|
|
|
|||
BIN
spec/fixtures/files/podcast.png
vendored
Normal file
BIN
spec/fixtures/files/podcast.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
|
|
@ -9,6 +9,12 @@ RSpec.describe Podcast, type: :model do
|
|||
it { is_expected.to validate_presence_of(:main_color_hex) }
|
||||
it { is_expected.to validate_presence_of(:feed_url) }
|
||||
|
||||
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
|
||||
expect { build(:podcast).save }.to have_enqueued_job.on_queue("podcasts_bust_cache").once
|
||||
|
|
@ -35,6 +41,20 @@ RSpec.describe Podcast, type: :model do
|
|||
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
|
||||
|
|
|
|||
|
|
@ -35,6 +35,13 @@ RSpec.describe User, type: :model do
|
|||
it { is_expected.to have_one(:pro_membership).dependent(:destroy) }
|
||||
|
||||
# rubocop:disable RSpec/NamedSubject
|
||||
it "has created_podcasts" do
|
||||
expect(subject).to have_many(:created_podcasts).
|
||||
class_name("Podcast").
|
||||
with_foreign_key(:creator_id).
|
||||
dependent(:nullify)
|
||||
end
|
||||
|
||||
it do
|
||||
expect(subject).to have_many(:access_grants).
|
||||
class_name("Doorkeeper::AccessGrant").
|
||||
|
|
|
|||
78
spec/requests/podcasts/podcast_create_spec.rb
Normal file
78
spec/requests/podcasts/podcast_create_spec.rb
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe "Podcast Create", type: :request do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
context "when unauthorized user" do
|
||||
it "redirects" do
|
||||
get new_podcast_path
|
||||
expect(response).to redirect_to(sign_up_path)
|
||||
end
|
||||
end
|
||||
|
||||
context "when signed in" do
|
||||
let(:valid_attributes) do
|
||||
{
|
||||
title: Faker::Hipster.words(number: 2).join(", "),
|
||||
description: Faker::Hipster.paragraph(sentence_count: 1),
|
||||
twitter_username: "hello-pod",
|
||||
image: fixture_file_upload("files/podcast.png", "image/png"),
|
||||
slug: "hello-pod",
|
||||
main_color_hex: "ffffff",
|
||||
website_url: Faker::Internet.url,
|
||||
feed_url: Faker::Internet.url
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
sign_in user
|
||||
end
|
||||
|
||||
it "renders new" do
|
||||
get new_podcast_path
|
||||
expect(response).to be_successful
|
||||
end
|
||||
|
||||
it "creates a podcast with valid attributes" do
|
||||
expect do
|
||||
post podcasts_path, params: { podcast: valid_attributes }
|
||||
end.to change(Podcast, :count).by(1)
|
||||
end
|
||||
|
||||
it "creates an unpublished podcast" do
|
||||
post podcasts_path, params: { podcast: valid_attributes }
|
||||
pod = Podcast.find_by(slug: valid_attributes[:slug])
|
||||
expect(pod.published).to be false
|
||||
end
|
||||
|
||||
it "creates a podcast with correct attributes" do
|
||||
post podcasts_path, params: { podcast: valid_attributes }
|
||||
pod = Podcast.find_by(slug: valid_attributes[:slug])
|
||||
expect(pod.title).to eq(valid_attributes[:title])
|
||||
end
|
||||
|
||||
it "creates a podcast_admin role when created by an owner" do
|
||||
post podcasts_path, params: { podcast: valid_attributes, i_am_owner: "1" }
|
||||
pod = Podcast.find_by(title: valid_attributes[:title])
|
||||
expect(user.has_role?(:podcast_admin, pod)).to be true
|
||||
end
|
||||
|
||||
it "doesn't create a podcast_admin role when not created by an owner" do
|
||||
post podcasts_path, params: { podcast: valid_attributes, i_am_owner: "" }
|
||||
pod = Podcast.find_by(title: valid_attributes[:title])
|
||||
expect(user.has_role?(:podcast_admin, pod)).to be false
|
||||
end
|
||||
|
||||
it "sets the creator" do
|
||||
post podcasts_path, params: { podcast: valid_attributes }
|
||||
pod = Podcast.find_by(title: valid_attributes[:title])
|
||||
expect(pod.creator).to eq(user)
|
||||
end
|
||||
|
||||
it "doesn't create with invalid attributes" do
|
||||
create(:podcast, slug: valid_attributes[:slug])
|
||||
post podcasts_path, params: { podcast: valid_attributes }
|
||||
expect(response.body).to include("Suggest a Podcast")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,7 +4,7 @@ RSpec.describe "PodcastEpisodesSpec", type: :request do
|
|||
describe "GET podcast episodes index" do
|
||||
it "renders page with proper sidebar" do
|
||||
get "/pod"
|
||||
expect(response.body).to include("If you know of a great dev podcast")
|
||||
expect(response.body).to include("Suggest a Podcast")
|
||||
end
|
||||
|
||||
it "shows reachable podcasts" do
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue