require "rails_helper" RSpec.describe VideosController, type: :controller do render_views let(:user) { create(:user) } let(:account) { user.primary_account } let(:project) { create(:project, account: user.primary_account) } let(:video) { create(:video, project: project) } before do sign_in(user) end describe "#index" do it "responds successfully" do get :index, params: { project_id: project } expect(response).to be_successful end it "has a search form" do create(:video, project: project) get :index, params: { project_id: project } expect(response.body).to have_button("search-button") end it "filters the videos by a query param" do create(:video, project: project, name: "First Video") create(:video, project: project, name: "Second Video") get :index, params: { project_id: project, query: "Second"}, xhr: true expect(response.body).not_to have_content("First Video") expect(response.body).to have_content("Second Video") end it "paginates the videos" do create_list(:video, 20, project: project) get :index, params: { project_id: project } expect(response.body).to have_link("2", href: project_videos_path(project, page: 2)) end it "renders content if there are existing videos" do video = create(:video, project: project, name: "My Video", number: "001", created_at: 1.day.ago) get :index, params: { project_id: project } expect(response.body).to have_content("1 day ago") expect(response.body).to have_content("My Video") expect(response.body).to have_content("001") expect(response.body).to have_content("video_file.mp4") expect(response.body).to have_content("Generating...") expect(response.body).to have_link("Upload New Video", href: landing_project_videos_path(project)) expect(response.body).to have_link("Edit", href: edit_video_path(video)) end context "when there are no records" do it "renders splash screen" do get :index, params: { project_id: project } expect(response.body).to have_link "Upload New Video" expect(response.body).to have_link schedule_demo end end context "when there are many records" do it "paginates the table" do create_list(:video, 20, project: project) get :index, params: { project_id: project } expect(response.body).to have_link("2", href: project_videos_path(project, page: 2)) end end end describe "#new" do it "responds successfully" do get :new, params: { project_id: project } expect(response).to be_successful end end describe "#landing" do it "responds successfully" do get :landing, params: { project_id: project } expect(response).to be_successful end end describe "#create" do it "responds with redirect" do post :create, params: { project_id: project, video: video_create_params } expect(response).to redirect_to(project_videos_path(project)) end it "creates a new video" do expect { post :create, params: { project_id: project, video: video_create_params } }.to change(Video, "count").by(1) expect(Video.last.video_editing_system).to eq "avid" end it "begins analyzing the video" do expect { post :create, params: { project_id: project, video: video_create_params } }.to have_enqueued_job(AnalyzeVideoJob).with(Video.last).and have_enqueued_job(AnalyzeAudioJob).with(Video.last) end it "delivers an admin notification" do assert_enqueued_emails 1 do post :create, params: { project_id: project, video: video_create_params } end end it "sets the flash" do post :create, params: { project_id: project, video: video_create_params } expect(flash.notice).to eq t("videos.create.notice") end it "logs analytics" do expect { post :create, params: { project_id: project, video: video_create_params } }.to have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_video_upload, user_agent: "Rails Testing", user_ip: "0.0.0.0") end context "when the record is invalid" do it "responds successfully" do post :create, params: { project_id: project, video: video_create_params(valid: false) } expect(response).to be_successful end end end describe "#edit" do it "responds successfully" do get :edit, params: { id: video } expect(response).to be_successful end end describe "#update" do it "redirects to the DeliverME page" do patch :update, params: { id: video, video: video_update_params } expect(response).to redirect_to(project_videos_path(project)) end it "updates the video attributes" do patch :update, params: { id: video, video: { name: "New Name" } } expect(video.reload.name).to eq "New Name" end it "sets the flash" do patch :update, params: { id: video, video: video_update_params } expect(flash.notice).to eq t("videos.update.notice") end context "when params are invalid" do it "re-renders the edit view" do allow_any_instance_of(Video).to receive(:update).and_return(false) patch :update, params: { id: video, video: video_update_params } expect(response).to be_successful end end context "with unpermitted file param" do it "does not update the record" do new_file = Rack::Test::UploadedFile.new file_fixture("video_file.mp4") expect { patch :update, params: { id: video, video: { name: "New Name", file: new_file } } }.to raise_error ActionController::UnpermittedParameters end end context "when edl_file changes" do let(:new_edl_file) do Rack::Test::UploadedFile.new file_fixture("sample-edl.edl"), "application/octet-stream" end it "delivers an admin notification" do assert_enqueued_email_with AdminMailer, :updated_video_edl_file, args: video do patch :update, params: { id: video, video: { edl_file: new_edl_file } } end end it "unpublishes the video" do video.publish_report! patch :update, params: { id: video, video: { edl_file: new_edl_file } } expect(video.reload).not_to be_report_published end end context "when graphics_only_edl_file changes" do let(:new_graphics_only_edl_file) do Rack::Test::UploadedFile.new file_fixture("sample-edl.edl"), "application/octet-stream" end it "delivers an admin notification" do assert_enqueued_email_with AdminMailer, :updated_video_graphics_only_edl_file, args: video do patch :update, params: { id: video, video: { graphics_only_edl_file: new_graphics_only_edl_file } } end end it "unpublishes the video" do video.publish_report! patch :update, params: { id: video, video: { graphics_only_edl_file: new_graphics_only_edl_file } } expect(video.reload).not_to be_report_published end end context "when audio_only_edl_file changes" do let(:new_audio_only_edl_file) do Rack::Test::UploadedFile.new file_fixture("sample-edl.edl"), "application/octet-stream" end it "delivers an admin notification" do assert_enqueued_email_with AdminMailer, :updated_video_audio_only_edl_file, args: video do patch :update, params: { id: video, video: { audio_only_edl_file: new_audio_only_edl_file } } end end it "unpublishes the video" do video.publish_report! patch :update, params: { id: video, video: { audio_only_edl_file: new_audio_only_edl_file } } expect(video.reload).not_to be_report_published end end context "when edl_file and graphics_only_edl_file and audio_only_edl_file does not change" do it "does not deliver an admin notification" do assert_no_enqueued_emails do patch :update, params: { id: video, video: { name: "New Name" } } end end it "does not unpublish the video" do video.publish_report! patch :update, params: { id: video, video: { name: "New Name" } } expect(video.reload).to be_report_published end end end private def video_create_params(valid: true) if valid attributes_for(:video, :with_graphics_only_edl_file, :with_audio_only_edl_file, name: "Test Video", video_editing_system: "avid") else attributes_for(:video, :with_graphics_only_edl_file, :with_audio_only_edl_file, name: "Test Video").except(:file) end end def video_update_params attributes_for(:video, :with_graphics_only_edl_file, :with_audio_only_edl_file, name: "Test Video").except(:file) end def schedule_demo t 'videos.splash.actions.book_demo' end end