require "rails_helper" describe GenerateContractsZipJob do let(:project) { create(:project) } let(:download) { create(:download, project: project) } let(:contract_template) { create(:contract_template, :project) } before do create(:appearance_release_with_contract_template, :native, project: project, person_name: "John Doe") create(:appearance_release_with_contract_template, :non_native, project: project) dir = Rails.root.join("spec", "fixtures", "files") files = ["contract.pdf", "AppearanceRelease.pdf"] # Attachments in the test environment do not persist to cloud storage # Therefore we want to stub calls to `open` with a cloud storage URL allow_any_instance_of(ReleaseContractCollectionService).to receive(:open).and_return(StringIO.new("file data")) allow_any_instance_of(ReleaseContractCollectionService).to receive(:build).and_yield(dir, files) end describe ".perform_later" do it "enqueues a background job for generating zip file" do expect { GenerateContractsZipJob.perform_later(project, download, "AppearanceRelease", project.appearance_releases.ids, '', '') }.to have_enqueued_job end end describe ".perform_now" do shared_examples "generates ZIP containig CSV file with all releases data" do it "generates ZIP containing CSV file with all releases data for all release types" do lowercase_plural = subject.constantize.model_name.plural GenerateContractsZipJob.perform_now(project, download, subject, project.public_send(lowercase_plural).ids, '', '') generated_zip = download.file.blob.download csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv" Zip::InputStream.open(StringIO.new(generated_zip)) do |io| while entry = io.get_next_entry next unless entry.name == csv_file_name csv_file = entry.get_input_stream.read release_class = Object.const_get subject release_headers = release_class.csv_headers release_headers.each do |header| expect(csv_file).to match header expect(csv_file).not_to match translation_missing end end end end end shared_examples "generates ZIP containig CSV file with specific releases data" do it "generates ZIP containing CSV file with all selected releases data for selected releases" do lowercase_plural = subject.constantize.model_name.plural all_releases = project.public_send(lowercase_plural) included_releases = all_releases.where(id: all_releases.ids[0..1]) not_included_releases = all_releases.where.not(id: all_releases.ids[0..1]) GenerateContractsZipJob.perform_now(project, download, subject, included_releases.ids, '', '') generated_zip = download.file.blob.download csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv" Zip::InputStream.open(StringIO.new(generated_zip)) do |io| while entry = io.get_next_entry next unless entry.name == csv_file_name csv_file = entry.get_input_stream.read release_class = Object.const_get subject release_headers = release_class.csv_headers release_headers.each do |header| expect(csv_file).to match header expect(csv_file).not_to match translation_missing end included_releases.each do |release| expect(csv_file).to match release.person_first_name end not_included_releases.each do |release| expect(csv_file).not_to match release.person_first_name end end end end it "generates ZIP containing CSV file with all filtered releases data for filtered releases" do if subject.respond_to?(:complete) && subject.respond_to?(:incomplete) lowercase_plural = subject.constantize.model_name.plural GenerateContractsZipJob.perform_now(project, download, subject, [], '', 'complete') complete_releases = project.public_send(lowercase_plural).complete incomplete_releases = project.public_send(lowercase_plural).incomplete generated_zip = download.file.blob.download csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv" Zip::InputStream.open(StringIO.new(generated_zip)) do |io| while entry = io.get_next_entry next unless entry.name == csv_file_name csv_file = entry.get_input_stream.read release_class = Object.const_get subject release_headers = release_class.csv_headers release_headers.each do |header| expect(csv_file).to match header expect(csv_file).not_to match translation_missing end complete_releases.each do |release| expect(csv_file).to match release.person_first_name end incomplete_releases.each do |release| expect(csv_file).not_to match release.person_first_name end end end end end it "generates ZIP containing CSV file with all search query matching releases" do lowercase_plural = subject.constantize.model_name.plural matched_releases = project.public_send(lowercase_plural).search('Brad') not_matched_releases = project.public_send(lowercase_plural).where.not(id: matched_releases.ids) GenerateContractsZipJob.perform_now(project, download, subject, [], 'Brad', '') generated_zip = download.file.blob.download csv_file_name = "#{project.name.parameterize}_#{lowercase_plural.gsub('_', '-')}.csv" Zip::InputStream.open(StringIO.new(generated_zip)) do |io| while entry = io.get_next_entry next unless entry.name == csv_file_name csv_file = entry.get_input_stream.read release_class = Object.const_get subject release_headers = release_class.csv_headers release_headers.each do |header| expect(csv_file).to match header expect(csv_file).not_to match translation_missing end matched_releases.each do |release| expect(csv_file).to match release.person_first_name end not_matched_releases.each do |release| expect(csv_file).not_to match release.person_first_name end end end end end it "updates a download record and creates attachment for it" do GenerateContractsZipJob.perform_now(project, download, "AppearanceRelease", project.appearance_releases.ids, '', '') expect(download.project).to eq project expect(download.release_type).to eq "AppearanceRelease" expect(download.name).to eq "my-video-project_appearance-releases" expect(download.status).to eq "success" expect(download.file).to be_attached end context "generates ZIP for acquired media releases" do let(:release) { create(:acquired_media_release_with_contract_template, :native, project: project, name: "John Doe") } let(:release2) { create(:acquired_media_release_with_contract_template, :native, project: project, name: "Jane Doe") } let(:release3) { create(:acquired_media_release_with_contract_template, :native, project: project, name: "Brad Doe") } subject { 'AcquiredMediaRelease' } it_behaves_like "generates ZIP containig CSV file with all releases data" it_behaves_like "generates ZIP containig CSV file with specific releases data" end context "generates ZIP for appearance releases" do let(:release) { create(:appearance_release_with_contract_template, :native, project: project, person_name: "John") } let(:incomplete_release) { create(:appearance_release_with_contract_template, project: project, person_name: "Jane") } let(:complete_release) { create(:appearance_release_with_contract_template, :non_native, project: project, person_name: "Brad") } subject { 'AppearanceRelease' } it_behaves_like "generates ZIP containig CSV file with all releases data" it_behaves_like "generates ZIP containig CSV file with specific releases data" end context "generates ZIP for location releases" do let(:release) { create(:location_release_with_contract_template, :native, project: project, name: "John") } let(:release2) { create(:location_release_with_contract_template, :native, project: project, name: "Jane") } let(:release3) { create(:location_release_with_contract_template, :native, project: project, name: "Brad") } subject { 'LocationRelease' } it_behaves_like "generates ZIP containig CSV file with all releases data" it_behaves_like "generates ZIP containig CSV file with specific releases data" end context "generates ZIP for material releases" do let(:release) { create(:material_release_with_contract_template, :native, project: project, name: "John") } let(:release2) { create(:material_release_with_contract_template, :native, project: project, name: "Jane") } let(:release3) { create(:material_release_with_contract_template, :native, project: project, name: "Brad") } subject { 'MaterialRelease' } it_behaves_like "generates ZIP containig CSV file with all releases data" it_behaves_like "generates ZIP containig CSV file with specific releases data" end context "generates ZIP for medical releases" do let(:release) { create(:medical_release_with_contract_template, :native, project: project, person_name: "John Doe") } let(:release2) { create(:medical_release_with_contract_template, :native, project: project, person_name: "Jane Doe") } let(:release3) { create(:medical_release_with_contract_template, :native, project: project, person_name: "Brad Doe") } subject { 'MedicalRelease' } it_behaves_like "generates ZIP containig CSV file with all releases data" it_behaves_like "generates ZIP containig CSV file with specific releases data" end context "generates ZIP for misc releases" do let(:release) { create(:misc_release_with_contract_template, :native, project: project, person_name: "John Doe") } let(:release2) { create(:misc_release_with_contract_template, :native, project: project, person_name: "Jane Doe") } let(:release3) { create(:misc_release_with_contract_template, :native, project: project, person_name: "Brad Doe") } subject { 'MiscRelease' } it_behaves_like "generates ZIP containig CSV file with all releases data" it_behaves_like "generates ZIP containig CSV file with specific releases data" end context "generates ZIP for music releases" do let(:release) { create(:music_release_with_contract_template, project: project, name: "John") } let(:release2) { create(:music_release_with_contract_template, project: project, name: "Jane") } let(:release3) { create(:music_release_with_contract_template, project: project, name: "Brad") } subject { 'MusicRelease' } it_behaves_like "generates ZIP containig CSV file with all releases data" it_behaves_like "generates ZIP containig CSV file with specific releases data" end context "generates ZIP for talent releases" do let(:release) { create(:talent_release_with_contract_template, :native, project: project, person_name: "John Doe") } let(:release2) { create(:talent_release_with_contract_template, :native, project: project, person_name: "Jane Doe") } let(:release3) { create(:talent_release_with_contract_template, :native, project: project, person_name: "Brad Doe") } subject { 'TalentRelease' } it_behaves_like "generates ZIP containig CSV file with all releases data" it_behaves_like "generates ZIP containig CSV file with specific releases data" end context "When there are errors" do let(:error) { StandardError.new("Contracts or contract templates not found.") } before do allow(ProjectsChannel).to receive(:broadcast_download_generation_update).with(download, I18n.t("contract_downloads.download.failure")) allow_any_instance_of(ReleaseContractCollectionService).to receive(:build).and_raise(StandardError, "Contracts or contract templates not found") end it "updates status to 'failure' and sends user a notification" do GenerateContractsZipJob.perform_now(project, download, "AppearanceRelease", project.appearance_releases.ids, '', '') expect(download.status).to eq "failure" expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(download, I18n.t("contract_downloads.download.failure")) end end end after do # Delete the file created in fixture. # Or the tests will fail on next run due to already existing files in existing zip. path = Rails.root.join("spec", "fixtures", "files") releases = %w[acquired-media appearance location material medical misc music talent] releases.each do |release| if File.exists? "#{path}/my-video-project_#{release}-releases.zip" File.delete("#{path}/my-video-project_#{release}-releases.zip") end end end private def translation_missing /translation missing/ end end