342 lines
12 KiB
Ruby
342 lines
12 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe BroadcastsController, type: :controller do
|
|
render_views
|
|
|
|
let(:user) { create(:user) }
|
|
let(:account) { user.primary_account }
|
|
let(:project) { create(:project, account: user.primary_account) }
|
|
|
|
before do
|
|
sign_in user
|
|
end
|
|
|
|
describe "#index" do
|
|
before do
|
|
stub_mux_live_stream
|
|
end
|
|
|
|
it "responds successfully" do
|
|
get :index, params: { project_id: project }
|
|
|
|
expect(response).to be_successful
|
|
end
|
|
|
|
it "renders content if theere are existing broadcasts" do
|
|
create(:broadcast, project: project, name: "Another Broadcast")
|
|
|
|
get :index, params: { project_id: project }
|
|
|
|
expect(response.body).to have_content "Another Broadcast"
|
|
expect(response.body).to have_content "Created"
|
|
expect(response.body).to have_content "less than a minute ago"
|
|
expect(response.body).to have_link "Create New Live Stream"
|
|
end
|
|
|
|
context "when there are no active broadcasts" do
|
|
it "renders splash screen" do
|
|
Broadcast.destroy_all
|
|
|
|
get :index, params: { project_id: project }
|
|
|
|
expect(response.body).to have_link create_stream
|
|
expect(response.body).to have_link schedule_demo
|
|
end
|
|
end
|
|
|
|
context "when there are many records" do
|
|
it "paginates the table" do
|
|
create_list(:broadcast, 20, project: project)
|
|
|
|
get :index, params: { project_id: project }
|
|
|
|
expect(response.body).to have_link("2", href: project_broadcasts_path(project, page: 2))
|
|
end
|
|
end
|
|
|
|
context "for xhr request" do
|
|
it "filters the broadcasts by a query param" do
|
|
create(:broadcast, project: project, skip_create_callback: true, name: "Stream by Adam")
|
|
create(:broadcast, project: project, skip_create_callback: true, name: "Stream by Zoe")
|
|
|
|
get :index, params: { project_id: project, query: "Zoe" }, xhr: true
|
|
|
|
expect(response.body).not_to have_content("Adam")
|
|
expect(response.body).to have_content("Zoe")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#new" do
|
|
it "responds successfully" do
|
|
get :new, params: { project_id: project }
|
|
|
|
expect(response).to be_successful
|
|
expect(assigns(:broadcast)).to be_a_new(Broadcast)
|
|
expect(response).to render_template(:new)
|
|
end
|
|
end
|
|
|
|
describe "#create" do
|
|
before do
|
|
stub_mux_live_stream
|
|
end
|
|
|
|
it "responds with a redirect" do
|
|
post :create, params: { project_id: project.id, broadcast: broadcast_params }
|
|
|
|
expect(response).to be_redirect
|
|
expect(flash.notice).not_to be_nil
|
|
end
|
|
|
|
it "does create a new record" do
|
|
expect {
|
|
post :create, params: { project_id: project.id, broadcast: broadcast_params }
|
|
}.to change(Broadcast, :count)
|
|
end
|
|
|
|
it "logs an event" do
|
|
expect {
|
|
post :create, params: { project_id: project.id, broadcast: broadcast_params }
|
|
}.to have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_live_stream, user_agent: "Rails Testing", user_ip: "0.0.0.0")
|
|
end
|
|
|
|
context "with invalid data" do
|
|
it "does not create a new record" do
|
|
expect {
|
|
post :create, params: { project_id: project.id, broadcast: { name: "" } }
|
|
}.not_to change(Broadcast, :count)
|
|
end
|
|
end
|
|
|
|
context "when Mux API error occurs" do
|
|
it "displays an alert message" do
|
|
allow_any_instance_of(Broadcast).to receive(:create_mux_live_stream).and_raise(MuxRuby::ApiError)
|
|
|
|
expect {
|
|
post :create, params: { project_id: project.id, broadcast: broadcast_params }
|
|
}.not_to change(Broadcast, :count)
|
|
|
|
expect(response).to be_redirect
|
|
expect(flash.alert).not_to be_nil
|
|
end
|
|
end
|
|
|
|
context "when ActiveResource API error occurs" do
|
|
it "displays an alert message" do
|
|
allow_any_instance_of(Broadcast).to receive(:create_mux_live_stream).and_raise(ActiveResource::ConnectionError.new(""))
|
|
|
|
expect {
|
|
post :create, params: { project_id: project.id, broadcast: broadcast_params }
|
|
}.not_to change(Broadcast, :count)
|
|
|
|
expect(response).to be_redirect
|
|
expect(flash.alert).not_to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#show" do
|
|
let(:broadcast) { create(:broadcast, project: project, name: "Another Broadcast") }
|
|
|
|
before do
|
|
stub_mux_live_stream
|
|
end
|
|
|
|
it "responds successfully" do
|
|
get :show, params: { project_id: project.id, id: broadcast.id }
|
|
|
|
expect(response).to be_successful
|
|
expect(assigns(:broadcast)).to eq(broadcast)
|
|
end
|
|
|
|
it "renders readonly share url" do
|
|
get :show, params: { project_id: project.id, id: broadcast.id }
|
|
|
|
expect(response.body).to have_button "Copy URL"
|
|
expect(response.body).to have_xpath "//input[@readonly][@value='#{broadcast_url(broadcast.token)}']"
|
|
end
|
|
|
|
it "displays zoom meeting button for zoom conference option" do
|
|
get :show, params: { project_id: project.id, id: broadcast.id }
|
|
|
|
expect(response.body).to have_link("Video Conference", href: project_broadcast_conference_meeting_url(project, broadcast))
|
|
end
|
|
|
|
it "displays microsoft teams meeting button for MS Teams conference option" do
|
|
ms_teams_broadcast = create(:broadcast, :ms_teams_conference, project: project )
|
|
get :show, params: { project_id: project.id, id: ms_teams_broadcast.id }
|
|
|
|
expect(response.body).to have_content 'MS Teams'
|
|
expect(response.body).to have_link 'Video Conference', href: project_broadcast_conference_meeting_url(project, ms_teams_broadcast)
|
|
end
|
|
|
|
it "assigns required variables" do
|
|
get :show, params: { project_id: project.id, id: broadcast.id }
|
|
|
|
expect(assigns(:conference_url)).to eq project_broadcast_conference_meeting_url(project, broadcast)
|
|
expect(assigns(:broadcast)).to eq broadcast
|
|
end
|
|
|
|
context "when there are no multi-view broadcasts" do
|
|
it "renders the view dropdown with just the current broadcast" do
|
|
get :show, params: { project_id: project, id: broadcast }
|
|
|
|
expect(response.body).to have_content "Switch View"
|
|
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Another Broadcast")
|
|
end
|
|
end
|
|
|
|
context "when there are multi-view broadcasts" do
|
|
it "renders the view dropdown with all the broadcasts" do
|
|
other_broadcast = create(:broadcast, project: project, name: "Some Other Broadcast")
|
|
|
|
get :show, params: { project_id: project, id: broadcast, multi_view_ids: [broadcast.id, other_broadcast.id] }
|
|
|
|
expect(response.body).to have_content "Switch View"
|
|
expect(response.body).to have_selector(".dropdown-menu .dropdown-item.active", text: "Another Broadcast")
|
|
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Some Other Broadcast")
|
|
end
|
|
end
|
|
|
|
context "when there are no recordings for the current broadcast" do
|
|
it "renders the view dropdown with a message" do
|
|
get :show, params: { project_id: project, id: broadcast }
|
|
|
|
expect(response.body).to have_content "Switch View"
|
|
expect(response.body).to have_selector(".dropdown-menu .dropdown-item", text: "Recordings will appear here")
|
|
end
|
|
end
|
|
|
|
context "when there are recordings available" do
|
|
it "renders the view dropdown with the recordings" do
|
|
recording = create(:broadcast_recording, broadcast: broadcast)
|
|
|
|
get :show, params: { project_id: project, id: broadcast }
|
|
|
|
expect(response.body).to have_content "Switch View"
|
|
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: recording.download_file_name)
|
|
end
|
|
end
|
|
|
|
context "when virtual director video embed is available" do
|
|
let(:broadcast) { create(:broadcast, project: project, name: "Another Broadcast",
|
|
director_mode_video_embed: "<iframe>video player</iframe>") }
|
|
|
|
it "renders the view dropdown with a director mode enable option" do
|
|
get :show, params: { project_id: project, id: broadcast }
|
|
|
|
expect(response.body).to have_content "Switch View"
|
|
expect(response.body).to have_selector(".dropdown-menu h5.dropdown-header", text: "Director Mode")
|
|
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Enable Director Mode")
|
|
end
|
|
|
|
context "when director mode is enabled" do
|
|
it "shows the video embed" do
|
|
get :show, params: { project_id: project, id: broadcast, director_mode: true }
|
|
|
|
expect(response.body).to have_selector("iframe", text: "video player")
|
|
end
|
|
|
|
it "renders the view dropdown with a director mode disable option" do
|
|
get :show, params: { project_id: project, id: broadcast, director_mode: true }
|
|
|
|
expect(response.body).to have_content "Switch View"
|
|
expect(response.body).to have_selector(".dropdown-menu h5.dropdown-header", text: "Director Mode")
|
|
expect(response.body).to have_selector(".dropdown-menu a.dropdown-item", text: "Disable Director Mode")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when video conference url has been overriden' do
|
|
let(:broadcast) { create(:broadcast, project: project, video_conference_url_override: 'https://test.com') }
|
|
|
|
it 'uses the override url for the video conference button' do
|
|
get :show, params: { project_id: project, id: broadcast }
|
|
|
|
expect(response.body).to have_link("Video Conference", href: 'https://test.com')
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#update" do
|
|
let!(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, project: project ) }
|
|
|
|
it "uploads files to broadcast" do
|
|
patch :update, params: { project_id: project.id, id: broadcast.id, broadcast: file_params }, xhr: true
|
|
|
|
expect(broadcast.files.count).to eq(1)
|
|
expect(broadcast.files.first.filename).to eq("contract.pdf")
|
|
end
|
|
|
|
it "sends an update to the broadcasts channel" do
|
|
allow(BroadcastsChannel).to receive(:broadcast_file_upload_updates)
|
|
|
|
patch :update, params: { project_id: project.id, id: broadcast.id, broadcast: file_params }, xhr: true
|
|
|
|
expect(BroadcastsChannel).to have_received(:broadcast_file_upload_updates)
|
|
end
|
|
|
|
it "regenerates token if #update is called without broadcast param" do
|
|
old_token = broadcast.token
|
|
patch :update, params: { project_id: project.id, id: broadcast.id }
|
|
|
|
expect(response).to redirect_to [project, broadcast]
|
|
expect(flash.notice).to eq token_reset_notice
|
|
expect(Broadcast.last.token).not_to eq old_token
|
|
end
|
|
end
|
|
|
|
describe "#destroy" do
|
|
let!(:broadcast_2) { create(:broadcast, :with_stream, skip_create_callback: true, project: project, name: "Another Broadcast") }
|
|
|
|
before do
|
|
allow_any_instance_of(MuxLiveStream).to receive(:destroy_stream).with(broadcast_2.stream_uid)
|
|
end
|
|
|
|
it "responds with redirect" do
|
|
delete :destroy, params: { project_id: project.id, id: broadcast_2.id }
|
|
|
|
expect(response).to be_redirect
|
|
expect(response).to redirect_to(project_broadcasts_path(project))
|
|
expect(flash.alert).not_to be_nil
|
|
end
|
|
|
|
it "destroys the record" do
|
|
expect {
|
|
delete :destroy, params: { project_id: project.id, id: broadcast_2.id }
|
|
}.to change(Broadcast, :count).by(-1)
|
|
end
|
|
end
|
|
|
|
after do
|
|
# Set the callback again or it will affect other test cases where the callback is required
|
|
Broadcast.set_callback(:create, :after, :create_mux_live_stream)
|
|
end
|
|
|
|
private
|
|
|
|
def broadcast_params
|
|
attributes_for(:broadcast)
|
|
end
|
|
|
|
def file_params
|
|
path = Rails.root.join("spec", "fixtures", "files", "contract.pdf")
|
|
contract_file = Rack::Test::UploadedFile.new(path, "application/pdf")
|
|
|
|
{ files: [contract_file] }
|
|
end
|
|
|
|
def schedule_demo
|
|
t 'broadcasts.splash.actions.book_demo'
|
|
end
|
|
|
|
def create_stream
|
|
t 'broadcasts.splash.actions.create_stream'
|
|
end
|
|
|
|
def token_reset_notice
|
|
t 'broadcasts.update.reset_notice'
|
|
end
|
|
end
|