Podcast ownership (#3546)
* Podcast#admins * Start with /internal/podcasts * Adding and removing podcast admin roles * Improve podcasts internal section * Fix podcast updating * More internal podcasts specs * Podcasts internal link
This commit is contained in:
parent
9f34dcd0eb
commit
3de1bdad02
9 changed files with 258 additions and 0 deletions
60
app/controllers/internal/podcasts_controller.rb
Normal file
60
app/controllers/internal/podcasts_controller.rb
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
class Internal::PodcastsController < Internal::ApplicationController
|
||||
layout "internal"
|
||||
|
||||
before_action :find_podcast, only: %i[edit update remove_admin add_admin]
|
||||
before_action :find_user, only: %i[remove_admin add_admin]
|
||||
|
||||
def index
|
||||
@podcasts = Podcast.joins(:podcast_episodes).
|
||||
select("podcasts.*, count(podcast_episodes) as count").
|
||||
group("podcasts.id").order("podcasts.created_at DESC").
|
||||
page(params[:page]).per(50)
|
||||
@podcasts = @podcasts.where("podcasts.title ILIKE :search", search: "%#{params[:search]}%") if params[:search].present?
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
def update
|
||||
if @podcast.update(podcast_params)
|
||||
redirect_to internal_podcasts_path, notice: "Podcast updated"
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def remove_admin
|
||||
removed_roles = @user.remove_role(:podcast_admin, @podcast)
|
||||
if removed_roles.empty?
|
||||
redirect_to edit_internal_podcast_path(@podcast), notice: "Error"
|
||||
else
|
||||
redirect_to internal_podcasts_path, notice: "Removed admin"
|
||||
end
|
||||
end
|
||||
|
||||
def add_admin
|
||||
role = @user.add_role(:podcast_admin, @podcast)
|
||||
if role.persisted?
|
||||
redirect_to internal_podcasts_path, notice: "Added admin"
|
||||
else
|
||||
redirect_to edit_internal_podcast_path(@podcast), notice: "Error"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_podcast
|
||||
@podcast = Podcast.find(params[:id])
|
||||
end
|
||||
|
||||
def find_user
|
||||
@user = User.find_by(id: params[:podcast][:user_id])
|
||||
redirect_to edit_internal_podcast_path(@podcast), notice: "No such user" unless @user
|
||||
end
|
||||
|
||||
def podcast_params
|
||||
allowed_params = %i[
|
||||
title feed_url
|
||||
]
|
||||
params.require(:podcast).permit(allowed_params)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
class Podcast < ApplicationRecord
|
||||
resourcify
|
||||
|
||||
has_many :podcast_episodes
|
||||
|
||||
mount_uploader :image, ProfileImageUploader
|
||||
|
|
@ -29,6 +31,10 @@ class Podcast < ApplicationRecord
|
|||
episode.to_a.first
|
||||
end
|
||||
|
||||
def admins
|
||||
User.with_role(:podcast_admin, self)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def unique_slug_including_users_and_orgs
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class Role < ApplicationRecord
|
|||
chatroom_beta_tester
|
||||
comment_banned
|
||||
pro
|
||||
podcast_admin
|
||||
]
|
||||
}
|
||||
scopify
|
||||
|
|
|
|||
43
app/views/internal/podcasts/edit.html.erb
Normal file
43
app/views/internal/podcasts/edit.html.erb
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<h1>
|
||||
<%= link_to @podcast.title, "/#{@podcast.slug}" %>
|
||||
</h1>
|
||||
<% if @podcast.admins.any? %>
|
||||
<p><strong>Admins: </strong></p>
|
||||
<ul>
|
||||
<% @podcast.admins.each do |admin| %>
|
||||
<%= form_for @podcast, url: remove_admin_internal_podcast_path(@podcast.id), html: { method: :delete } do |f| %>
|
||||
<li>
|
||||
<%= link_to "@#{admin.username}", "/#{admin.username}" %>
|
||||
<%= f.hidden_field :user_id, value: admin.id %>
|
||||
<%= f.submit "Remove" %>
|
||||
</li>
|
||||
<br>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<p>There are no admins for this podcast.</p>
|
||||
<% end %>
|
||||
|
||||
<%= form_for @podcast, url: add_admin_internal_podcast_path(@podcast.id), html: { method: :post } do |f| %>
|
||||
<div>
|
||||
<%= f.label "Add Admin (by user_id) " %>
|
||||
<%= f.text_field :user_id, value: "" %>
|
||||
<%= f.submit "Add Admin" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= form_for [:internal, @podcast] do |f| %>
|
||||
<hr>
|
||||
<div>
|
||||
<%= f.label :title %>
|
||||
<%= f.text_field :title %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.label :feed_url %>
|
||||
<%= f.text_field :feed_url %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.submit %>
|
||||
</div>
|
||||
<% end %>
|
||||
42
app/views/internal/podcasts/index.html.erb
Normal file
42
app/views/internal/podcasts/index.html.erb
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<style>
|
||||
.alert {
|
||||
border: 2px red solid;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>Podcasts</h1>
|
||||
|
||||
<%= form_tag("/internal/podcasts", method: "get") do %>
|
||||
<%= label_tag(:search, "Find by title:") %>
|
||||
<%= text_field_tag(:search, params[:search]) %>
|
||||
<%= submit_tag("Search") %>
|
||||
<% end %>
|
||||
|
||||
<%= paginate @podcasts %>
|
||||
<br>
|
||||
<div class="wrapper-7" style="font-weight: 600; border-bottom: 2px solid black;">
|
||||
<div>ID</div>
|
||||
<div>Title</div>
|
||||
<div>Feed URL</div>
|
||||
<div>Episodes</div>
|
||||
<div>Reachable</div>
|
||||
<div>Status Notice</div>
|
||||
<div>Admins</div>
|
||||
</div>
|
||||
|
||||
<% @podcasts.each do |podcast| %>
|
||||
<div class="wrapper-7" style="border-bottom: 1px solid grey; padding: 10px;">
|
||||
<div class="grid-item"><%= podcast.id %></div>
|
||||
<div class="grid-item"><a href="<%= edit_internal_podcast_path(podcast) %>"><%= podcast.title %></a></div>
|
||||
<div class="grid-item"><a href="<%= podcast.feed_url %>"><%= podcast.feed_url %></a></div>
|
||||
<div class="grid-item"><%= podcast.podcast_episodes.count %></div>
|
||||
<div class="grid-item"><%= podcast.reachable %></div>
|
||||
<div class="grid-item"><%= podcast.status_notice %></div>
|
||||
<div class="grid-item">
|
||||
<% podcast.admins.pluck(:username).each do |username| %>
|
||||
<%= link_to "@#{username}", "/#{username}" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= paginate @podcasts %>
|
||||
|
|
@ -42,6 +42,12 @@
|
|||
padding: 2px;
|
||||
}
|
||||
|
||||
.wrapper-7 {
|
||||
display: grid;
|
||||
grid-template-columns: 5% 15% 25% 10% 10% 20% 15%;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.wrapper-3 {
|
||||
display: grid;
|
||||
grid-template-columns: 25% 40% 25%%;
|
||||
|
|
@ -137,6 +143,7 @@
|
|||
<% controller_names.each do |name| %>
|
||||
<li class="<%= "active" if controller_name == name %>"><a href="/internal/<%= name %>"><%= name %></a></li>
|
||||
<% end %>
|
||||
<li class="<%= "active" if controller_name == "podcasts" %>"><a href="/internal/podcasts">pod</a></li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ Rails.application.routes.draw do
|
|||
resources :feedback_messages, only: %i[index show]
|
||||
resources :listings, only: %i[index edit update destroy], controller: "classified_listings"
|
||||
resources :pages, only: %i[index new create edit update destroy]
|
||||
resources :podcasts, only: %i[index edit update destroy] do
|
||||
member do
|
||||
post :add_admin
|
||||
delete :remove_admin
|
||||
end
|
||||
end
|
||||
resources :reactions, only: [:update]
|
||||
resources :chat_channels, only: %i[index create update]
|
||||
resources :reports, only: %i[index show], controller: "feedback_messages" do
|
||||
|
|
|
|||
|
|
@ -128,4 +128,30 @@ RSpec.describe Podcast, type: :model do
|
|||
expect(podcast.existing_episode(item)).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#admins" do
|
||||
let(:podcast) { create(:podcast) }
|
||||
let(:podcast2) { create(:podcast) }
|
||||
let(:podcast3) { create(:podcast) }
|
||||
let(:user) { create(:user) }
|
||||
let(:user2) { create(:user) }
|
||||
let(:user3) { create(:user) }
|
||||
|
||||
before do
|
||||
user.add_role(:podcast_admin, podcast)
|
||||
user2.add_role(:podcast_admin, podcast)
|
||||
user.add_role(:podcast_admin, podcast3)
|
||||
user3.add_role(:podcast_admin, podcast2)
|
||||
user3.add_role(:podcast_admin, podcast2)
|
||||
[user, user2, user3].each(&:save)
|
||||
end
|
||||
|
||||
it "returns proper admins" do
|
||||
expect(podcast.admins.sort).to eq([user, user2].sort)
|
||||
end
|
||||
|
||||
it "returns proper admins for podcast3" do
|
||||
expect(podcast3.admins).to eq([user])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
67
spec/requests/internal/podcasts_spec.rb
Normal file
67
spec/requests/internal/podcasts_spec.rb
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe "/internal/podcasts", type: :request do
|
||||
let(:admin) { create(:user, :super_admin) }
|
||||
let(:podcast) { create(:podcast) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
sign_in admin
|
||||
end
|
||||
|
||||
describe "GET /internal/podcasts" do
|
||||
before do
|
||||
create_list(:podcast, 3)
|
||||
user.add_role(:podcast_admin, Podcast.order("random()").first)
|
||||
end
|
||||
|
||||
it "renders success" do
|
||||
get internal_podcasts_path
|
||||
expect(response).to be_success
|
||||
end
|
||||
end
|
||||
|
||||
describe "Adding admin" do
|
||||
it "adds an admin" do
|
||||
expect do
|
||||
post add_admin_internal_podcast_path(podcast.id), params: { podcast: { user_id: user.id } }
|
||||
end.to change(Role, :count).by(1)
|
||||
user.reload
|
||||
expect(user.has_role?(:podcast_admin, podcast)).to be true
|
||||
end
|
||||
|
||||
it "does nothing when adding an admin for non-existent user" do
|
||||
post add_admin_internal_podcast_path(podcast.id), params: { podcast: { user_id: user.id + 1 } }
|
||||
expect(response).to redirect_to(edit_internal_podcast_path(podcast))
|
||||
end
|
||||
end
|
||||
|
||||
describe "Removing admin" do
|
||||
it "removes an admin" do
|
||||
user.add_role(:podcast_admin, podcast)
|
||||
expect do
|
||||
delete remove_admin_internal_podcast_path(podcast.id), params: { podcast: { user_id: user.id } }
|
||||
end.to change(Role, :count).by(-1)
|
||||
expect(user.has_role?(:podcast_admin, podcast)).to be false
|
||||
end
|
||||
|
||||
it "does nothing when removing an admin for non-existent user" do
|
||||
delete remove_admin_internal_podcast_path(podcast.id), params: { podcast: { user_id: user.id + 1 } }
|
||||
expect(response).to redirect_to(edit_internal_podcast_path(podcast))
|
||||
end
|
||||
end
|
||||
|
||||
describe "Updating" do
|
||||
it "updates" do
|
||||
put internal_podcast_path(podcast), params: { podcast: { title: "hello", feed_url: "https://pod.example.com/rss.rss" } }
|
||||
podcast.reload
|
||||
expect(podcast.title).to eq("hello")
|
||||
expect(podcast.feed_url).to eq("https://pod.example.com/rss.rss")
|
||||
end
|
||||
|
||||
it "redirects after update" do
|
||||
put internal_podcast_path(podcast), params: { podcast: { title: "hello", feed_url: "https://pod.example.com/rss.rss" } }
|
||||
expect(response).to redirect_to(internal_podcasts_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue