require "rails_helper" RSpec.describe MusicReleasesController, type: :controller do render_views let(:user) { create(:user) } let(:account) { user.primary_account } let(:project) { create(:project, account: user.primary_account) } before :each 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 "renders content" do release = create(:music_release, project: project, name: "My Release") create(:note, notable: release, content: "Some notes here") get :index, params: { project_id: project } expect(response.body).to have_content "My Release" expect(response.body).to have_content "0" expect(response.body).to have_content "1" expect(response.body).to have_content "1" expect(response.body).to have_content "Some notes here" expect(response.body).to have_link "Import Release" expect(response.body).to have_content "Manage" end context "when there are no music releases" do it "renders an empty message" do get :index, params: { project_id: project } expect(response.body).to have_content("Music Releases will appear here") end end context "when there are many records" do it "paginates the table" do create_list(:music_release, 20, project: project) get :index, params: { project_id: project } expect(response.body).to have_link("2", href: project_music_releases_path(project, page: 2)) end end context "for xhr request" do it "filters the releases by a query param" do music_releases = [ create(:music_release, name: "Extreme Music Collection", project: project), create(:music_release, name: "Audio Networks Music Collection", project: project), ] get :index, params: { project_id: project, query: "Audio" }, xhr: true expect(response.body).not_to have_content("Extreme") expect(response.body).to have_content("Audio") end end end describe "#new" do it "responds successfully" do get :new, params: { project_id: project } expect(response).to be_successful end it "initializes with 5 composers and 2 publishers" do get :new, params: { project_id: project } expect(assigns(:music_release).composers.size).to eq 5 expect(assigns(:music_release).publishers.size).to eq 2 end end describe "#create" do it "responds successfully" do expect { post :create, params: { project_id: project, music_release: music_release_params } }.to change(MusicRelease, :count).by(1) expect(response).to be_redirect expect(response).to redirect_to [project, :music_releases] expect(flash.notice).to be_present end it "creates nested file info records" do expect { post :create, params: { project_id: project, music_release: music_release_params.merge( file_infos_attributes: { 0 => attributes_for(:file_info) } ) } }.to change(FileInfo, :count).by(1) expect(MusicRelease.last.file_infos.size).to eq(1) end it "creates nested composer records" do expect { post :create, params: { project_id: project, music_release: music_release_params.merge( composers_attributes: { 0 => { name: "name", affiliation: "affiliation", percentage: 100, cae_number: "cae123456789", }, } ) } }.to change(Composer, :count).by(1) expect(MusicRelease.last.composers.size).to eq(1) end it "creates nested publisher records" do expect { post :create, params: { project_id: project, music_release: music_release_params.merge( publishers_attributes: { 0 => attributes_for(:publisher), } ) } }.to change(Publisher, :count).by(1) expect(MusicRelease.last.publishers.size).to eq(1) end it "enqueues tagging job" do expect { post :create, params: { project_id: project, music_release: music_release_params } }.to have_enqueued_job(SetTagsForReleasableJob).with(MusicRelease.last) end context "when the record would be invalid" do before :each do allow_any_instance_of(MusicRelease).to receive(:save).and_return(false) end it "re-renders the form" do post :create, params: { project_id: project, music_release: music_release_params.merge( publishers_attributes: { 0 => attributes_for(:publisher), } ) } expect(response).to render_template :new expect(flash.notice).to be_nil end it "does not enqueue any jobs" do expect { post :create, params: { project_id: project, music_release: music_release_params } }.not_to have_enqueued_job end it "initializes with 5 composers and 2 publishers" do post :create, params: { project_id: project, music_release: music_release_params.merge( publishers_attributes: { 0 => attributes_for(:publisher), } ) } expect(assigns(:music_release).composers.size).to eq 5 expect(assigns(:music_release).publishers.size).to eq 2 end end end describe "#edit" do let(:music_release) { create(:music_release, project: project) } it "responds successfully" do get :edit, params: { id: music_release } expect(response).to be_successful end it "initializes with 5 composers and 2 publishers" do get :edit, params: { id: music_release } expect(assigns(:music_release).composers.size).to eq 5 expect(assigns(:music_release).publishers.size).to eq 2 end end describe "#update" do let(:music_release) { create(:music_release, project: project) } it "responds successfully" do put :update, params: { id: music_release, music_release: { name: "Updated name" } } expect(response).to redirect_to [project, :music_releases] expect(flash.notice).to eq "The music release has been updated" expect(music_release.reload.name).to eq "Updated name" end context "when the record would be invalid" do before :each do allow_any_instance_of(MusicRelease).to receive(:update).and_return(false) end it "re-renders the form" do put :update, params: { id: music_release, music_release: music_release_params } expect(response).to render_template :edit expect(flash.notice).to be_nil end end end describe "#destroy" do let!(:music_release) { create(:music_release, project: project) } it "destroys the record" do expect { delete :destroy, params: { id: music_release } }.to change(MusicRelease, :count).by(-1) end it "redirects to project and sets alert" do delete :destroy, params: { id: music_release } expect(response).to redirect_to [project, :music_releases] expect(flash.alert).to eq "The music release has been deleted" end end private def music_release_params attributes_for(:music_release).merge( composers_attributes: [attributes_for(:composer)], publishers_attributes: [attributes_for(:publisher)], ).merge(exploitable_rights_params) end def exploitable_rights_params { applicable_medium_id: ApplicableMedium.last.id, applicable_medium_text: "applicable_media", territory_id: Territory.last.id, territory_text: "territory", term_id: Term.last.id, term_text: "term", restriction_id: Restriction.last.id, restriction_text: "restrictions", } end end