Initial commit
This commit is contained in:
18
spec/models/account_auth_spec.rb
Normal file
18
spec/models/account_auth_spec.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AccountAuth, type: :model do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:user) }
|
||||
it { is_expected.to belong_to(:account) }
|
||||
end
|
||||
|
||||
describe "enums" do
|
||||
it { is_expected.to define_enum_for(:role).with_values(associate: 0, project_manager: 1, account_manager: 2) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
describe "#user_id" do
|
||||
it { is_expected.to validate_uniqueness_of(:user_id).scoped_to(:account_id).with_message("already added to account.") }
|
||||
end
|
||||
end
|
||||
end
|
||||
236
spec/models/account_spec.rb
Normal file
236
spec/models/account_spec.rb
Normal file
@@ -0,0 +1,236 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Account do
|
||||
describe "associations" do
|
||||
it { is_expected.to have_many(:users).through(:account_auths) }
|
||||
it { is_expected.to have_many(:projects).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:contract_templates).through(:projects) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
it { is_expected.to validate_presence_of(:slug) }
|
||||
|
||||
describe "#slug uniqueness" do
|
||||
subject { build(:account) }
|
||||
|
||||
it "validates uniqueness of slug" do
|
||||
allow(subject).to receive(:set_slug)
|
||||
expect(subject).to validate_presence_of(:slug)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "generating a slug" do
|
||||
context "when name and slug are not present" do
|
||||
it "does not generate a slug" do
|
||||
account = build(:account, name: nil, slug: nil)
|
||||
|
||||
account.save
|
||||
|
||||
expect(account.slug).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when a name is present and a slug is not present" do
|
||||
it "generates a slug" do
|
||||
account = build(:account, name: "Half Pint Courter", slug: nil)
|
||||
|
||||
account.save
|
||||
|
||||
expect(account.slug).to eq "half-pint-courter"
|
||||
end
|
||||
end
|
||||
|
||||
context "when name and slug are both present" do
|
||||
it "does not generate a slug" do
|
||||
account = build(:account, name: "Half Pint Courter", slug: "half-pint-courter2")
|
||||
|
||||
account.save
|
||||
|
||||
expect(account.slug).to eq "half-pint-courter2"
|
||||
end
|
||||
end
|
||||
|
||||
context "when name is not unique" do
|
||||
it "generates a unique slug" do
|
||||
account_one = create(:account, name: "Half Pint Courter", slug: "half-pint-courter")
|
||||
account_two = create(:account, name: "Half Pint Courter", slug: "half-pint-courter-2")
|
||||
account_three = build(:account, name: "Half Pint Courter", slug: nil)
|
||||
|
||||
account_three.save
|
||||
|
||||
expect(account_three.slug).to eq "half-pint-courter-3"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#storage_total" do
|
||||
it "sums videos, release photos, contracts, signatures, recordings" do
|
||||
video_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "video_file.mp4"), "video/mp4")
|
||||
recording_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "video_file.mp4"), "video/mp4")
|
||||
photo_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "person_photo.png"), "image/png")
|
||||
contract_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "contract.pdf"), "application/pdf")
|
||||
signature_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "signature.png"), "image/png")
|
||||
edl_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "sample-edl.edl"), "application/octet-stream")
|
||||
|
||||
expect(video_file.size).to eq 1_055_736
|
||||
expect(recording_file.size).to eq 1_055_736
|
||||
expect(edl_file.size).to eq 440
|
||||
expect(photo_file.size).to eq 910
|
||||
expect(contract_file.size).to eq 12
|
||||
expect(signature_file.size).to eq 2_509
|
||||
|
||||
account = create(:account)
|
||||
project = create(:project, account: account)
|
||||
video = create(:video, project: project, file: video_file, edl_file: edl_file)
|
||||
appearance_release = create(:appearance_release, project: project, person_photo: photo_file, contract: contract_file, signature: signature_file)
|
||||
talent_release = create(:talent_release, project: project, photos: [photo_file], contract: contract_file, signature: signature_file)
|
||||
material_release = create(:material_release, project: project, photos: [photo_file], contract: contract_file, signature: signature_file)
|
||||
location_release = create(:location_release, project: project, photos: [photo_file], contract: contract_file, signature: signature_file)
|
||||
acquired_media_release = create(:acquired_media_release, project: project, contract: contract_file)
|
||||
import = create(:import, project: project, file: contract_file)
|
||||
music_release = create(:music_release, project: project, contract: contract_file)
|
||||
zoom_meeting = create(:zoom_meeting, project: project, recording: recording_file)
|
||||
|
||||
expect(account.storage_total).to eq 2_125_672
|
||||
end
|
||||
|
||||
it "sums only for projects tied to account" do
|
||||
video_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "video_file.mp4"), "video/mp4")
|
||||
edl_file = Rack::Test::UploadedFile.new(Rails.root.join("spec", "fixtures", "files", "sample-edl.edl"), "application/octet-stream")
|
||||
|
||||
expect(video_file.size).to eq 1_055_736
|
||||
expect(edl_file.size).to eq 440
|
||||
|
||||
account = create(:account)
|
||||
project = create(:project, account: account)
|
||||
other_account_project = create(:project, account: create(:account))
|
||||
create(:video, project: project, file: video_file, edl_file: edl_file)
|
||||
create(:video, project: other_account_project, file: video_file, edl_file: edl_file)
|
||||
|
||||
expect(account.storage_total).to eq 1_056_176
|
||||
end
|
||||
|
||||
it "fails when we do not account for models that have attachments" do
|
||||
models_with_attachments = [
|
||||
AppearanceRelease,
|
||||
TalentRelease,
|
||||
MaterialRelease,
|
||||
LocationRelease,
|
||||
AcquiredMediaRelease,
|
||||
Import,
|
||||
MusicRelease,
|
||||
Video,
|
||||
SampleAppearanceRelease,
|
||||
ActiveStorage::Blob,
|
||||
ActionText::RichText,
|
||||
Directory,
|
||||
Download,
|
||||
User,
|
||||
Broadcast,
|
||||
Account,
|
||||
ZoomMeeting
|
||||
]
|
||||
Rails.application.eager_load!
|
||||
ActiveRecord::Base.descendants.each do |model|
|
||||
if model.reflections.keys.any? { |x| x.match? /_attachments?/ }
|
||||
unless models_with_attachments.include?(model)
|
||||
fail("Warning! #{model} may have an unaccounted for attachment, please add to #storage_total")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#me_suite_enabled?" do
|
||||
it "returns true when plan_uid is me_suite" do
|
||||
expect(build(:account, plan_uid: "me_suite").me_suite_enabled?).to eq true
|
||||
end
|
||||
|
||||
it "returns false when plan_uid is not me_suite" do
|
||||
expect(build(:account, plan_uid: "deliverme").me_suite_enabled?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#deliverme_enabled?" do
|
||||
it "returns true when plan_uid is me_suite" do
|
||||
expect(build(:account, plan_uid: "me_suite").deliverme_enabled?).to eq true
|
||||
end
|
||||
|
||||
it "returns true when plan_uid is deliverme" do
|
||||
expect(build(:account, plan_uid: "deliverme").deliverme_enabled?).to eq true
|
||||
end
|
||||
|
||||
it "returns false when plan_uid is not deliverme" do
|
||||
expect(build(:account, plan_uid: "releaseme").deliverme_enabled?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#directme_enabled?" do
|
||||
it "returns true when plan_uid is me_suite" do
|
||||
expect(build(:account, plan_uid: "me_suite").directme_enabled?).to eq true
|
||||
end
|
||||
|
||||
it "returns true when plan_uid is directme" do
|
||||
expect(build(:account, plan_uid: "directme").directme_enabled?).to eq true
|
||||
end
|
||||
|
||||
it "returns false when plan_uid is not directme" do
|
||||
expect(build(:account, plan_uid: "releaseme").directme_enabled?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#releaseme_enabled?" do
|
||||
it "returns true when plan_uid is me_suite" do
|
||||
expect(build(:account, plan_uid: "me_suite").releaseme_enabled?).to eq true
|
||||
end
|
||||
|
||||
it "returns true when plan_uid is releaseme" do
|
||||
expect(build(:account, plan_uid: "releaseme").releaseme_enabled?).to eq true
|
||||
end
|
||||
|
||||
it "returns false when plan_uid is not releaseme" do
|
||||
expect(build(:account, plan_uid: "deliverme").releaseme_enabled?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#plan_name" do
|
||||
context "when plan_uid deliverme" do
|
||||
it "returns DeliverME" do
|
||||
expect(build(:account, plan_uid: "deliverme").plan_name).to eq "DeliverME"
|
||||
end
|
||||
end
|
||||
|
||||
context "when plan_uid directme" do
|
||||
it "returns DirectME" do
|
||||
expect(build(:account, plan_uid: "directme").plan_name).to eq "DirectME"
|
||||
end
|
||||
end
|
||||
|
||||
context "when plan_uid releaseme" do
|
||||
it "returns ReleaseME" do
|
||||
expect(build(:account, plan_uid: "releaseme").plan_name).to eq "ReleaseME"
|
||||
end
|
||||
end
|
||||
|
||||
context "when plan_uid me_suite" do
|
||||
it "returns ME Suite" do
|
||||
expect(build(:account, plan_uid: "me_suite").plan_name).to eq "ME Suite"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#managers" do
|
||||
it "returns users who have the account manager role" do
|
||||
account = build(:account)
|
||||
account_manager = create(:user, :account_manager, accounts: [account])
|
||||
project_manager = create(:user, :manager, accounts: [account])
|
||||
|
||||
managers = account.managers
|
||||
|
||||
expect(managers).to include(account_manager)
|
||||
expect(managers).not_to include(project_manager)
|
||||
end
|
||||
end
|
||||
end
|
||||
61
spec/models/acquired_media_release_spec.rb
Normal file
61
spec/models/acquired_media_release_spec.rb
Normal file
@@ -0,0 +1,61 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe AcquiredMediaRelease do
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
it_behaves_like "a releasable"
|
||||
it_behaves_like "a taggable"
|
||||
|
||||
context "for native releases" do
|
||||
it { is_expected.to validate_attachment_of(:signature).on(:native) }
|
||||
end
|
||||
|
||||
context "for non-native releases" do
|
||||
it { is_expected.to validate_attachment_of(:contract).on(:non_native) }
|
||||
end
|
||||
|
||||
describe "associations" do
|
||||
it { is_expected.to have_many(:file_infos).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "nested attributes" do
|
||||
it { is_expected.to accept_nested_attributes_for(:file_infos) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
|
||||
describe "#person_email" do
|
||||
it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
|
||||
it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "attachments" do
|
||||
it { is_expected.to respond_to(:contract) }
|
||||
end
|
||||
|
||||
describe "#uses_edl?" do
|
||||
it { is_expected.to be_uses_edl }
|
||||
end
|
||||
|
||||
describe "#contract_file_name" do
|
||||
it "includes project name, release type, signed at date, release number and release name" do
|
||||
release = create(:acquired_media_release_with_contract_template, signed_at: Date.new(2020, 2, 10), name: "sample release")
|
||||
|
||||
expect(release.contract_file_name).to eq("my-video-project_acquired_media_2020.02.10_1_sample-release")
|
||||
end
|
||||
|
||||
context "when signed at is nil" do
|
||||
it "uses the created at date" do
|
||||
release = create(:acquired_media_release_with_contract_template,
|
||||
signed_at: nil,
|
||||
created_at: DateTime.new(2020, 2, 10, 12, 0, 0),
|
||||
name: "sample release")
|
||||
|
||||
expect(release.contract_file_name).to eq("my-video-project_acquired_media_2020.02.10_1_sample-release")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
77
spec/models/address_spec.rb
Normal file
77
spec/models/address_spec.rb
Normal file
@@ -0,0 +1,77 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Address do
|
||||
describe "#format" do
|
||||
it "prints the address in a single line" do
|
||||
address = Address.new("100 Test Lane", "Suite 1", "New York", "NY", "10001", "US")
|
||||
|
||||
expect(address.to_s).to eq("100 Test Lane, Suite 1, New York, NY 10001, US")
|
||||
end
|
||||
|
||||
it "prints the address condensed into two lines" do
|
||||
address = Address.new("100 Test Lane", "Suite 1", "New York", "NY", "10001", "US")
|
||||
|
||||
actual = address.to_s(format: :condensed)
|
||||
expected = <<~END
|
||||
100 Test Lane, Suite 1
|
||||
New York, NY 10001, US
|
||||
END
|
||||
|
||||
expect(actual).to eq(expected.chomp)
|
||||
end
|
||||
|
||||
it "prints the address in full postal format" do
|
||||
address = Address.new("100 Test Lane", "Suite 1", "New York", "NY", "10001", "US")
|
||||
|
||||
actual = address.to_s(format: :full)
|
||||
expected = <<~END
|
||||
100 Test Lane
|
||||
Suite 1
|
||||
New York, NY 10001
|
||||
US
|
||||
END
|
||||
|
||||
expect(actual).to eq(expected.chomp)
|
||||
end
|
||||
|
||||
context "when there is no 2nd street line" do
|
||||
it "does not add extra commas to the single line format" do
|
||||
address = Address.new("100 Test Lane", "", "New York", "NY", "10001", "US")
|
||||
|
||||
expect(address.to_s).to eq("100 Test Lane, New York, NY 10001, US")
|
||||
end
|
||||
|
||||
it "does not add extra newlines to the full format" do
|
||||
address = Address.new("100 Test Lane", "", "New York", "NY", "10001", "US")
|
||||
|
||||
actual = address.to_s(format: :full)
|
||||
expected = <<~END
|
||||
100 Test Lane
|
||||
New York, NY 10001
|
||||
US
|
||||
END
|
||||
|
||||
expect(actual).to eq(expected.chomp)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#present?" do
|
||||
it "returns false when no parts of the address are present" do
|
||||
address = Address.new("", "", "", "", "", "")
|
||||
|
||||
expect(address).not_to be_present
|
||||
end
|
||||
it "returns true when any part of the address is present" do
|
||||
%w(street1 street2 city state zip country).each do |part|
|
||||
address = Address.new("", "", "", "", "", "")
|
||||
|
||||
expect(address).not_to be_present
|
||||
|
||||
address.public_send("#{part}=", "value")
|
||||
|
||||
expect(address).to be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
75
spec/models/analysis_notification_spec.rb
Normal file
75
spec/models/analysis_notification_spec.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe AnalysisNotification, type: :model do
|
||||
describe "#build" do
|
||||
context "for audio type" do
|
||||
it "returns AudioAnalysisNotification subclass" do
|
||||
notification = described_class.build("audio", "job_id")
|
||||
|
||||
expect(notification).to be_a(AnalysisNotification::AudioAnalysisNotification)
|
||||
expect(notification.job_id).to eq "job_id"
|
||||
end
|
||||
end
|
||||
|
||||
context "for video type" do
|
||||
it "returns VideoAnalysisNotification subclass" do
|
||||
notification = described_class.build("video", "job_id")
|
||||
|
||||
expect(notification).to be_a(AnalysisNotification::VideoAnalysisNotification)
|
||||
expect(notification.job_id).to eq "job_id"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe AnalysisNotification::VideoAnalysisNotification do
|
||||
let!(:video) { create(:video, analysis_uid: "job_id") }
|
||||
|
||||
subject { described_class.new("job_id") }
|
||||
|
||||
describe "#video" do
|
||||
it "fetches video using job id" do
|
||||
expect(subject.video).to eq video
|
||||
end
|
||||
end
|
||||
|
||||
describe "#success!" do
|
||||
it "updates status of the video" do
|
||||
subject.success!
|
||||
expect(video.reload).to be_analysis_success
|
||||
end
|
||||
end
|
||||
|
||||
describe "#failure!" do
|
||||
it "updates status of the video" do
|
||||
subject.failure!
|
||||
expect(video.reload).to be_analysis_failure
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe AnalysisNotification::AudioAnalysisNotification do
|
||||
let!(:video) { create(:video, audio_analysis_uid: "job_id") }
|
||||
|
||||
subject { described_class.new("job_id") }
|
||||
|
||||
describe "#video" do
|
||||
it "fetches video using job id" do
|
||||
expect(subject.video).to eq video
|
||||
end
|
||||
end
|
||||
|
||||
describe "#success!" do
|
||||
it "updates status of the video" do
|
||||
subject.success!
|
||||
expect(video.reload).to be_audio_analysis_success
|
||||
end
|
||||
end
|
||||
|
||||
describe "#failure!" do
|
||||
it "updates status of the video" do
|
||||
subject.failure!
|
||||
expect(video.reload).to be_audio_analysis_failure
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
156
spec/models/app_host_spec.rb
Normal file
156
spec/models/app_host_spec.rb
Normal file
@@ -0,0 +1,156 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe AppHost do
|
||||
describe "#domain" do
|
||||
it "returns the domain set in the environment" do
|
||||
env = { "DOMAIN" => "test-domain.com" }
|
||||
|
||||
app_domain = AppHost.new(env, "development")
|
||||
|
||||
expect(app_domain.domain).to eq("test-domain.com")
|
||||
end
|
||||
|
||||
context "when domain is not set in the environment" do
|
||||
it "returns the default domain for the development environment" do
|
||||
env = {}
|
||||
|
||||
app_domain = AppHost.new(env, "development")
|
||||
|
||||
expect(app_domain.domain).to eq("localhost")
|
||||
end
|
||||
|
||||
it "returns the default domain for the test environment" do
|
||||
env = {}
|
||||
|
||||
app_domain = AppHost.new(env, "test")
|
||||
|
||||
expect(app_domain.domain).to eq("localhost")
|
||||
end
|
||||
|
||||
it "returns the default domain for the production environment" do
|
||||
env = {}
|
||||
|
||||
app_domain = AppHost.new(env, "production")
|
||||
|
||||
expect(app_domain.domain).to eq("bigmedia.ai")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#port" do
|
||||
it "returns the port set in the environment" do
|
||||
env = { "WEB_PORT" => 4000 }
|
||||
|
||||
app_domain = AppHost.new(env, "development")
|
||||
|
||||
expect(app_domain.port).to eq(4000)
|
||||
end
|
||||
|
||||
context "when port is not set in the environment" do
|
||||
it "returns the port domain for the development environment" do
|
||||
env = {}
|
||||
|
||||
app_domain = AppHost.new(env, "development")
|
||||
|
||||
expect(app_domain.port).to eq(3000)
|
||||
end
|
||||
|
||||
it "returns the default port for the test environment" do
|
||||
env = {}
|
||||
|
||||
app_domain = AppHost.new(env, "test")
|
||||
|
||||
expect(app_domain.port).to eq(31337)
|
||||
end
|
||||
|
||||
it "returns the default port for the production environment" do
|
||||
env = {}
|
||||
|
||||
app_domain = AppHost.new(env, "production")
|
||||
|
||||
expect(app_domain.port).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#domain_with_port" do
|
||||
it "returns the combination of domain with the port" do
|
||||
env = { "DOMAIN" => "test-domain.com", "WEB_PORT" => 4000 }
|
||||
|
||||
app_domain = AppHost.new(env, "development")
|
||||
|
||||
expect(app_domain.domain_with_port).to eq("test-domain.com:4000")
|
||||
end
|
||||
|
||||
context "when port is not specified at all" do
|
||||
it "omits the port portion of the URL" do
|
||||
env = { "DOMAIN" => "test-domain.com" }
|
||||
|
||||
app_domain = AppHost.new(env, "production")
|
||||
|
||||
expect(app_domain.domain_with_port).to eq("test-domain.com")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#use_ssl" do
|
||||
it "returns true if the value set in the environment" do
|
||||
env = { "USE_SSL" => "true" }
|
||||
|
||||
app_domain = AppHost.new(env, "development")
|
||||
|
||||
expect(app_domain).to be_using_ssl
|
||||
end
|
||||
|
||||
context "when the value is not set in the environment" do
|
||||
it "returns the default value for the development environment" do
|
||||
env = {}
|
||||
|
||||
app_domain = AppHost.new(env, "development")
|
||||
|
||||
expect(app_domain).not_to be_using_ssl
|
||||
end
|
||||
|
||||
it "returns the default value for the test environment" do
|
||||
env = {}
|
||||
|
||||
app_domain = AppHost.new(env, "test")
|
||||
|
||||
expect(app_domain).not_to be_using_ssl
|
||||
end
|
||||
|
||||
it "returns the default value for the production environment" do
|
||||
env = {}
|
||||
|
||||
app_domain = AppHost.new(env, "production")
|
||||
|
||||
expect(app_domain).to be_using_ssl
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "#protocol" do
|
||||
it "returns 'https' when using SSL" do
|
||||
env = { "USE_SSL" => true }
|
||||
|
||||
app_domain = AppHost.new(env)
|
||||
|
||||
expect(app_domain.protocol).to eq :https
|
||||
end
|
||||
|
||||
it "returns 'http's when not using SSL" do
|
||||
env = {}
|
||||
|
||||
app_domain = AppHost.new(env)
|
||||
|
||||
expect(app_domain.protocol).to eq :http
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def stub_env(key, value)
|
||||
allow(ENV).to receive(:fetch).with(key).and_return(value)
|
||||
end
|
||||
end
|
||||
176
spec/models/appearance_release_spec.rb
Normal file
176
spec/models/appearance_release_spec.rb
Normal file
@@ -0,0 +1,176 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AppearanceRelease do
|
||||
it_behaves_like 'a contractable'
|
||||
it_behaves_like 'an exploitable'
|
||||
it_behaves_like 'a notable'
|
||||
it_behaves_like 'a releasable'
|
||||
it_behaves_like 'a taggable'
|
||||
|
||||
it { is_expected.to respond_to(:photos) }
|
||||
it { is_expected.to respond_to(:photo) }
|
||||
|
||||
describe 'associations' do
|
||||
it { is_expected.to have_many(:video_release_confirmations).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:confirmed_videos).source(:video).through(:video_release_confirmations) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { is_expected.to allow_content_types('image/png', 'image/jpeg').for(:person_photo) }
|
||||
it { is_expected.not_to allow_content_types('application/pdf', 'image/gif').for(:person_photo) }
|
||||
it { is_expected.to allow_value('test@test.com', nil).for(:person_email) }
|
||||
it { is_expected.not_to allow_values('foo', 'test@foo', 'N/A').for(:person_email) }
|
||||
it { is_expected.to validate_presence_of(:person_first_name) }
|
||||
it { is_expected.to validate_presence_of(:person_last_name) }
|
||||
|
||||
context 'for native releases' do
|
||||
it { is_expected.to validate_attachment_of(:person_photo).on(:native) }
|
||||
it { is_expected.to validate_attachment_of(:signature).on(:native) }
|
||||
|
||||
it 'validates person_photo_is_acceptable on new records' do
|
||||
appearance_release = build(:appearance_release)
|
||||
allow(BrayniacAI::Validation).to receive(:create).and_return(double(:validation, valid: false, error: 'api error'))
|
||||
|
||||
expect(appearance_release.valid?(:native)).to eq false
|
||||
expect(appearance_release.errors[:person_photo]).to eq ['api error']
|
||||
end
|
||||
|
||||
it 'does not validate person_photo_is_acceptable on existing records' do
|
||||
appearance_release = create(:appearance_release, :native)
|
||||
|
||||
expect(appearance_release.valid?(:native)).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context 'for non-native releases' do
|
||||
it 'fails to create release if nothing is attached' do
|
||||
release = create(:appearance_release, :without_person_photo)
|
||||
|
||||
expect(release.valid?(:non_native)).to eq false
|
||||
end
|
||||
|
||||
it 'creates release if only contract is attached' do
|
||||
release = create(:appearance_release, :without_person_photo, :non_native)
|
||||
|
||||
expect(release.valid?(:non_native)).to eq true
|
||||
end
|
||||
|
||||
it 'creates release if only person_photo is attached' do
|
||||
release = create(:appearance_release, :with_person_photo_only)
|
||||
|
||||
expect(release.valid?(:non_native)).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the signer is a minor' do
|
||||
subject { build(:appearance_release, minor: true) }
|
||||
|
||||
it { is_expected.to validate_presence_of(:guardian_first_name) }
|
||||
it { is_expected.to validate_presence_of(:guardian_last_name) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'attachments' do
|
||||
it { is_expected.to respond_to(:contract) }
|
||||
it { is_expected.to respond_to(:person_photo) }
|
||||
it { is_expected.to respond_to(:signature) }
|
||||
end
|
||||
|
||||
describe 'scopes' do
|
||||
describe '.complete' do
|
||||
it 'returns records that have both a person photo and a contract' do
|
||||
skip "Test is inconsistently failing in CI"
|
||||
|
||||
without_photo_or_contract = create(:appearance_release, person_photo: nil, contract: nil)
|
||||
with_photo_without_contract = create(:appearance_release, contract: nil)
|
||||
without_photo_with_contract = create(:appearance_release, :non_native, person_photo: nil)
|
||||
with_photo_and_contract = create(:appearance_release, :non_native)
|
||||
|
||||
complete_releases = described_class.complete
|
||||
all_releases = described_class.all
|
||||
|
||||
expect(complete_releases).not_to include(all_releases[0])
|
||||
expect(complete_releases).not_to include(all_releases[1])
|
||||
expect(complete_releases).not_to include(all_releases[2])
|
||||
expect(complete_releases).to include(all_releases[3])
|
||||
end
|
||||
end
|
||||
|
||||
describe '.incomplete' do
|
||||
it 'returns records that are missing either a person photo or a contract' do
|
||||
skip "Test is inconsistently failing in CI"
|
||||
|
||||
without_photo_or_contract = create(:appearance_release, person_photo: nil, contract: nil)
|
||||
with_photo_without_contract = create(:appearance_release, contract: nil)
|
||||
without_photo_with_contract = create(:appearance_release, :non_native, person_photo: nil)
|
||||
with_photo_and_contract = create(:appearance_release, :non_native)
|
||||
|
||||
incomplete_releases = described_class.incomplete
|
||||
all_releases = described_class.all
|
||||
|
||||
expect(incomplete_releases).to include(all_releases[0])
|
||||
expect(incomplete_releases).to include(all_releases[1])
|
||||
expect(incomplete_releases).to include(all_releases[2])
|
||||
expect(incomplete_releases).not_to include(all_releases[3])
|
||||
end
|
||||
end
|
||||
|
||||
describe '.with_person_photo' do
|
||||
it 'returns records that have a person photo attachment' do
|
||||
with_photo = create(:appearance_release, :with_person_photo)
|
||||
without_photo = create(:appearance_release, :without_person_photo)
|
||||
|
||||
results = described_class.with_person_photo
|
||||
|
||||
expect(results.size).to eq 1
|
||||
expect(results).to include(with_photo)
|
||||
expect(results).not_to include(without_photo)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#native?' do
|
||||
it 'returns true when the release has a signature' do
|
||||
release = build(:appearance_release, :native)
|
||||
|
||||
expect(release).to be_native
|
||||
end
|
||||
end
|
||||
|
||||
describe '#uses_edl?' do
|
||||
it { is_expected.to be_uses_edl }
|
||||
end
|
||||
|
||||
describe '#photos' do
|
||||
it 'returns photo if it is attached' do
|
||||
ar = create(:appearance_release)
|
||||
expect(ar.photos).to eq [ar.photo]
|
||||
end
|
||||
|
||||
it 'returns empty list if photo is not attached' do
|
||||
ar = AppearanceRelease.new
|
||||
expect(ar.photos).to eq []
|
||||
end
|
||||
end
|
||||
|
||||
describe '#contract_file_name' do
|
||||
it 'includes signed timestamp, release number, and person name' do
|
||||
release = create(:appearance_release_with_contract_template, signed_at: Date.new(2020, 2, 10), person_first_name: 'John', person_last_name: 'Doe')
|
||||
|
||||
expect(release.contract_file_name).to eq('my-video-project_appearance_2020.02.10_1_doe-john')
|
||||
end
|
||||
|
||||
context 'when signed at is nil' do
|
||||
it 'uses the created at date' do
|
||||
release = create(:appearance_release_with_contract_template,
|
||||
signed_at: nil,
|
||||
created_at: DateTime.new(2020, 2, 10, 12, 0, 0),
|
||||
person_first_name: 'John', person_last_name: 'Doe')
|
||||
|
||||
expect(release.contract_file_name).to eq('my-video-project_appearance_2020.02.10_1_doe-john')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
5
spec/models/applicable_medium_spec.rb
Normal file
5
spec/models/applicable_medium_spec.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe ApplicableMedium, type: :model do
|
||||
it_behaves_like "a freeformable"
|
||||
end
|
||||
68
spec/models/audio_analysis_spec.rb
Normal file
68
spec/models/audio_analysis_spec.rb
Normal file
@@ -0,0 +1,68 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe AudioAnalysis, type: :model do
|
||||
let(:video) { build(:video, :with_audio_only_edl_file, audio_analysis_uid: "123abc") }
|
||||
|
||||
subject { AudioAnalysis.new(video) }
|
||||
|
||||
describe "#to_hash" do
|
||||
it "includes edl" do
|
||||
allow(ENV).to receive(:[])
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("mybucket")
|
||||
|
||||
expect(subject.to_hash).to include({
|
||||
edl_bucket_name: "mybucket",
|
||||
edl_object_name: video.audio_only_edl_file.key,
|
||||
})
|
||||
end
|
||||
|
||||
it "includes acquired media audio file infos" do
|
||||
create(:acquired_media_release, project: video.project, file_infos: [
|
||||
build(:file_info, id: 1, filename: "acquired_media_1.mp3", content_type: "audio/mp3"),
|
||||
build(:file_info, id: 2, filename: "acquired_media_2.aif", content_type: "audio/aif"),
|
||||
build(:file_info, id: 3, filename: "acquired_media_3.wav", content_type: "audio/wav"),
|
||||
build(:file_info, id: 4, filename: "acquired_media_4.mov", content_type: "video/mov"),
|
||||
build(:file_info, id: 5, filename: "acquired_media_4.mp4", content_type: "video/mp4"),
|
||||
])
|
||||
|
||||
expect(subject.to_hash).to have_key(:acquired_audio)
|
||||
expect(subject.to_hash[:acquired_audio]).to include(id: 1, filename: "acquired_media_1.mp3")
|
||||
expect(subject.to_hash[:acquired_audio]).to include(id: 2, filename: "acquired_media_2.aif")
|
||||
expect(subject.to_hash[:acquired_audio]).to include(id: 3, filename: "acquired_media_3.wav")
|
||||
expect(subject.to_hash[:acquired_audio]).not_to include(id: 4, filename: "acquired_media_4.mov")
|
||||
expect(subject.to_hash[:acquired_audio]).not_to include(id: 5, filename: "acquired_media_5.mp4")
|
||||
end
|
||||
|
||||
it "includes music release file infos" do
|
||||
create(:music_release,
|
||||
project: video.project,
|
||||
file_infos: [
|
||||
build(:file_info, id: 1, filename: "original_music_1.mp3"),
|
||||
build(:file_info, id: 2, filename: "original_music_2.mp3"),
|
||||
],
|
||||
composers: build_list(:composer, 1),
|
||||
publishers: build_list(:publisher, 1),
|
||||
)
|
||||
|
||||
expect(subject.to_hash).to have_key(:original_music)
|
||||
expect(subject.to_hash[:original_music]).to include(id: 1, filename: "original_music_1.mp3",
|
||||
composers: "Beethoven, Affiliation, 100.0",
|
||||
publishers: "Jingle Punks, Affiliation, 100.0")
|
||||
expect(subject.to_hash[:original_music]).to include(id: 2, filename: "original_music_2.mp3",
|
||||
composers: "Beethoven, Affiliation, 100.0",
|
||||
publishers: "Jingle Punks, Affiliation, 100.0")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#results" do
|
||||
it "returns response from API request using audio analysis uid" do
|
||||
response = double("response", results: [])
|
||||
edl_event_gateway = double("edl_event_gateway", fps: 29.97, edl_offset_seconds: 0)
|
||||
allow(EdlEventGateway).to receive(:new).and_return(edl_event_gateway)
|
||||
allow(BrayniacAI::AudioRecognition).to receive(:find).and_return(response)
|
||||
|
||||
expect(subject.results).to eq(response.results)
|
||||
expect(BrayniacAI::AudioRecognition).to have_received(:find).with(video.audio_analysis_uid, params: { fps: 29.97, edl_offset_seconds: 0 })
|
||||
end
|
||||
end
|
||||
end
|
||||
55
spec/models/audio_confirmation_spec.rb
Normal file
55
spec/models/audio_confirmation_spec.rb
Normal file
@@ -0,0 +1,55 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe AudioConfirmation do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:video) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:time_elapsed) }
|
||||
|
||||
describe "confirmation_type" do
|
||||
it "validates only original_music and library_music are allowed" do
|
||||
expect(build(:audio_confirmation, confirmation_type: "original_music").valid?).to eq true
|
||||
expect(build(:audio_confirmation, confirmation_type: "library_music").valid?).to eq true
|
||||
expect(build(:audio_confirmation, confirmation_type: "unknown_music").valid?).to eq false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#appears_at" do
|
||||
it "returns formatted timecode" do
|
||||
audio_confirmation = build(:audio_confirmation, time_elapsed: "1.039")
|
||||
|
||||
expect(audio_confirmation.appears_at).to eq "00:00:01:01"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#presented_source_file_name" do
|
||||
context "when confirmation_type is original_music" do
|
||||
it "returns source_file_name with (O) prefix" do
|
||||
audio_confirmation = build(:audio_confirmation, confirmation_type: "original_music", source_file_name: "source_file_name")
|
||||
|
||||
expect(audio_confirmation.presented_source_file_name).to eq "(O) source_file_name"
|
||||
end
|
||||
end
|
||||
|
||||
context "when confirmation_type is library_music" do
|
||||
it "returns source_file_name with (L) prefix" do
|
||||
audio_confirmation = build(:audio_confirmation, confirmation_type: "library_music", source_file_name: "source_file_name")
|
||||
|
||||
expect(audio_confirmation.presented_source_file_name).to eq "(L) source_file_name"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#confirmation_type_library?" do
|
||||
it "returns true when confirmation_type is library" do
|
||||
expect(build(:audio_confirmation, :library)).to be_confirmation_type_library
|
||||
end
|
||||
|
||||
it "returns false when confirmation_type is not library" do
|
||||
expect(build(:audio_confirmation, :original)).not_to be_confirmation_type_library
|
||||
end
|
||||
end
|
||||
end
|
||||
54
spec/models/audio_files_for_request_spec.rb
Normal file
54
spec/models/audio_files_for_request_spec.rb
Normal file
@@ -0,0 +1,54 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe AudioFilesForRequest do
|
||||
let(:video) do
|
||||
create(:video, :with_audio_only_edl_file, analysis_uid: "analysis_uid") do |video|
|
||||
video.file.key = "awesome"
|
||||
video.audio_only_edl_file.key = "sauce"
|
||||
end
|
||||
end
|
||||
|
||||
subject { described_class.new(video, "offset") }
|
||||
|
||||
describe "#start_timecode_offset" do
|
||||
it "returns given start_timecode_offset" do
|
||||
expect(subject.start_timecode_offset).to eq "offset"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#file_object_name" do
|
||||
it "returns file key" do
|
||||
expect(subject.file_object_name).to eq "awesome"
|
||||
end
|
||||
|
||||
it "returns nil when no video file attached" do
|
||||
video.file.purge
|
||||
expect(subject.file_object_name).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "#edl_file_object_name" do
|
||||
it "returns audio edl file key" do
|
||||
expect(subject.edl_file_object_name).to eq "sauce"
|
||||
end
|
||||
|
||||
it "returns nil when no video file attached" do
|
||||
video.audio_only_edl_file.purge
|
||||
expect(subject.edl_file_object_name).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "#aws_bucket_name" do
|
||||
it "returns AWS bucket name" do
|
||||
allow(ENV).to receive(:[])
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("bucket")
|
||||
expect(subject.aws_bucket_name).to eq "bucket"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#job_id" do
|
||||
it "returns the analysis uid of the video" do
|
||||
expect(subject.job_id).to eq "analysis_uid"
|
||||
end
|
||||
end
|
||||
end
|
||||
56
spec/models/blank_contract_spec.rb
Normal file
56
spec/models/blank_contract_spec.rb
Normal file
@@ -0,0 +1,56 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe BlankContract do
|
||||
describe 'rendering the contract' do
|
||||
let(:project) { build(:project) }
|
||||
|
||||
it 'works with appearance releases' do
|
||||
appearance_release = create(:appearance_release_with_contract_template, project: project, person_name: 'Jane Doe')
|
||||
|
||||
result = render_contract_html_for(appearance_release)
|
||||
|
||||
expect(result).not_to be_nil
|
||||
end
|
||||
|
||||
it 'works with talent releases' do
|
||||
talent_release = create(:talent_release_with_contract_template, project: project, person_name: 'Jane Doe')
|
||||
|
||||
result = render_contract_html_for(talent_release)
|
||||
|
||||
expect(result).not_to be_nil
|
||||
end
|
||||
|
||||
it 'works with location releases' do
|
||||
location_release = create(:location_release_with_contract_template, project: project, person_name: 'Jane Doe')
|
||||
|
||||
result = render_contract_html_for(location_release)
|
||||
|
||||
expect(result).not_to be_nil
|
||||
end
|
||||
|
||||
it 'works with material releases' do
|
||||
material_release = create(:material_release_with_contract_template, project: project, person_name: 'Jane Doe')
|
||||
|
||||
result = render_contract_html_for(material_release)
|
||||
|
||||
expect(result).not_to be_nil
|
||||
end
|
||||
|
||||
it 'renders a QR code, serial number and warning not to copy' do
|
||||
material_release = create(:material_release_with_contract_template, project: project, person_name: 'Jane Doe')
|
||||
result = render_contract_html_for(material_release)
|
||||
|
||||
expect(result).to include 'serial-number'
|
||||
expect(result).to include 'DO NOT COPY'
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Reaching into the object's internals a bit here to avoid generating a PDF unnecessarily
|
||||
def render_contract_html_for(releasable)
|
||||
BlankContract.new(releasable).send(:as_html)
|
||||
end
|
||||
end
|
||||
11
spec/models/bookmark_spec.rb
Normal file
11
spec/models/bookmark_spec.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Bookmark do
|
||||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:video) }
|
||||
end
|
||||
|
||||
describe "enums" do
|
||||
it { is_expected.to define_enum_for(:category).with_values("Other": 0, "Audio": 1, "Graphics": 2, "Video": 3) }
|
||||
end
|
||||
end
|
||||
46
spec/models/broadcast_recording_spec.rb
Normal file
46
spec/models/broadcast_recording_spec.rb
Normal file
@@ -0,0 +1,46 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe BroadcastRecording, type: :model do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:broadcast) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
subject { described_class.new(asset_uid: "asset_uid", asset_playback_uid: "playback_uid", file_name: "medium.mp4") }
|
||||
it { is_expected.to validate_uniqueness_of(:asset_uid) }
|
||||
end
|
||||
|
||||
describe "#delegations" do
|
||||
it { should delegate_method(:name).to(:broadcast).with_prefix(:broadcast) }
|
||||
end
|
||||
|
||||
describe "#order_by_recent" do
|
||||
subject { described_class }
|
||||
it { is_expected.to respond_to(:order_by_recent) }
|
||||
end
|
||||
|
||||
describe "#download_url" do
|
||||
let(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, name: "My Broadcast") }
|
||||
let(:broadcast_recording) { create(:broadcast_recording, broadcast: broadcast) }
|
||||
|
||||
it "should have a download url" do
|
||||
download_file_name = broadcast_recording.send(:download_file_name)
|
||||
expect(broadcast_recording.download_url).to eq("https://stream.mux.com/asset_playback_uid/high.mp4?download=#{download_file_name}")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#download_file_name" do
|
||||
it "includes the name of the live stream and the created datetime" do
|
||||
broadcast = create(:broadcast, skip_create_callback: true, name: "My Broadcast")
|
||||
recording = create(:broadcast_recording, broadcast: broadcast, created_at: DateTime.new(2020, 05, 14, 15, 30, 00))
|
||||
file_name = recording.download_file_name
|
||||
|
||||
expect(file_name).to eq "my-broadcast_date_2020-05-14_time_15-30-00"
|
||||
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
|
||||
end
|
||||
62
spec/models/broadcast_spec.rb
Normal file
62
spec/models/broadcast_spec.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Broadcast, type: :model do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:project) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
it { is_expected.to have_secure_token(:token) }
|
||||
end
|
||||
|
||||
describe "enums" do
|
||||
it { is_expected.to define_enum_for(:status).with_values([:created, :active, :idle]) }
|
||||
it { is_expected.to define_enum_for(:streamer_status).with_values([:idle, :connected, :recording, :disconnected]).with_prefix(:streamer) }
|
||||
end
|
||||
|
||||
describe "callbacks" do
|
||||
context "#after_create" do
|
||||
let(:broadcast) { build(:broadcast, name: "My Broadcast") }
|
||||
let(:live_stream_data) { OpenStruct.new(data: OpenStruct.new(id: "stream_id", stream_key: "stream_key")) }
|
||||
let(:live_stream_playback_data) { OpenStruct.new(data: OpenStruct.new(id: "playback_id")) }
|
||||
|
||||
it 'triggers create_mux_live_stream' do
|
||||
expect(broadcast).to receive(:create_mux_live_stream)
|
||||
|
||||
broadcast.run_callbacks(:create)
|
||||
end
|
||||
|
||||
it 'assigns stream_id, stream_key and stream_playback_id to broadcast' do
|
||||
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream).and_return(live_stream_data)
|
||||
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream_playback_id).and_return(live_stream_playback_data)
|
||||
|
||||
broadcast.save
|
||||
|
||||
expect(broadcast.stream_uid).to eq "stream_id"
|
||||
expect(broadcast.stream_key).to eq "stream_key"
|
||||
expect(broadcast.stream_playback_uid).to eq "playback_id"
|
||||
end
|
||||
end
|
||||
|
||||
context "#after_destroy" do
|
||||
let(:broadcast) { create(:broadcast, :with_stream, skip_create_callback: true, name: "My Broadcast") }
|
||||
|
||||
it "triggers destroy_mux_live_stream" do
|
||||
allow(broadcast).to receive(:destroy_mux_live_stream)
|
||||
broadcast.run_callbacks(:destroy)
|
||||
|
||||
expect(broadcast).to have_received(:destroy_mux_live_stream)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#zoom_meeting_url" do
|
||||
it { is_expected.to delegate_method(:zoom_meeting_url).to(:project) }
|
||||
end
|
||||
|
||||
describe "#order_by_recent" do
|
||||
subject { described_class }
|
||||
it { is_expected.to respond_to(:order_by_recent) }
|
||||
end
|
||||
end
|
||||
9
spec/models/composer_spec.rb
Normal file
9
spec/models/composer_spec.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Composer do
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
it { is_expected.to validate_presence_of(:affiliation) }
|
||||
it { is_expected.to validate_presence_of(:percentage) }
|
||||
end
|
||||
end
|
||||
58
spec/models/contract_spec.rb
Normal file
58
spec/models/contract_spec.rb
Normal file
@@ -0,0 +1,58 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Contract do
|
||||
describe '#filename' do
|
||||
it 'delegates to the releasable for the name' do
|
||||
project = build_stubbed(:project, name: "My Project")
|
||||
releasable = double("releasable", contract_file_name: "test")
|
||||
|
||||
contract = Contract.new(releasable)
|
||||
|
||||
expect(contract.filename).to eq("test.pdf")
|
||||
expect(contract.filename("xls")).to eq("test.xls")
|
||||
end
|
||||
end
|
||||
|
||||
describe "rendering the contract" do
|
||||
let(:project) { build(:project) }
|
||||
|
||||
it 'works with appearance releases' do
|
||||
appearance_release = create(:appearance_release_with_contract_template, project: project, person_name: "Jane Doe")
|
||||
|
||||
result = render_contract_html_for(appearance_release)
|
||||
|
||||
expect(result).not_to be_nil
|
||||
end
|
||||
|
||||
it 'works with talent releases' do
|
||||
talent_release = create(:talent_release_with_contract_template, project: project, person_name: "Jane Doe")
|
||||
|
||||
result = render_contract_html_for(talent_release)
|
||||
|
||||
expect(result).not_to be_nil
|
||||
end
|
||||
|
||||
it 'works with location releases' do
|
||||
location_release = create(:location_release_with_contract_template, project: project, person_name: "Jane Doe")
|
||||
|
||||
result = render_contract_html_for(location_release)
|
||||
|
||||
expect(result).not_to be_nil
|
||||
end
|
||||
|
||||
it 'works with material releases' do
|
||||
material_release = create(:material_release_with_contract_template, project: project, person_name: "Jane Doe")
|
||||
|
||||
result = render_contract_html_for(material_release)
|
||||
|
||||
expect(result).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Reaching into the object's internals a bit here to avoid generating a PDF unnecessarily
|
||||
def render_contract_html_for(releasable)
|
||||
Contract.new(releasable).send(:as_html)
|
||||
end
|
||||
end
|
||||
79
spec/models/contract_template_preview_spec.rb
Normal file
79
spec/models/contract_template_preview_spec.rb
Normal file
@@ -0,0 +1,79 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ContractTemplatePreview do
|
||||
describe '#build_releasable' do
|
||||
it 'fills missing contract template data' do
|
||||
ct = ContractTemplate.new
|
||||
ct.release_type = :talent
|
||||
preview = ContractTemplatePreview.new(ct)
|
||||
expect do
|
||||
preview.build_releasable
|
||||
end.to change { ct.name }
|
||||
.and change { ct.body.to_s }
|
||||
.and change { ct.guardian_clause.to_s }
|
||||
end
|
||||
|
||||
it 'does not overwrite existing contract template data' do
|
||||
ct = build(:contract_template)
|
||||
preview = ContractTemplatePreview.new(ct)
|
||||
expect do
|
||||
preview.build_releasable
|
||||
end.to not_change { ct.name }
|
||||
.and not_change { ct.body.to_s }
|
||||
.and not_change { ct.guardian_clause.to_s }
|
||||
end
|
||||
|
||||
describe 'fills releasable with dummy data' do
|
||||
it 'with guardian details when guardian clause is present' do
|
||||
ct = build(:contract_template)
|
||||
preview = ContractTemplatePreview.new(ct)
|
||||
releasable = preview.build_releasable
|
||||
expect(releasable.attributes).to include(expected_dummy_data)
|
||||
end
|
||||
|
||||
it 'with guardian details when guardian clause is not present' do
|
||||
ct = ContractTemplate.new
|
||||
ct.release_type = :appearance
|
||||
preview = ContractTemplatePreview.new(ct)
|
||||
releasable = preview.build_releasable
|
||||
expect(releasable.attributes).to include(expected_dummy_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def expected_dummy_data
|
||||
{
|
||||
'id' => nil,
|
||||
'person_first_name' => 'Dummy',
|
||||
'person_last_name' => 'Person',
|
||||
'person_address' => 'Street 1, Street 2, City, State 12345, Country',
|
||||
'person_phone' => '00 111 222 333 4444',
|
||||
'updated_at' => nil,
|
||||
'minor' => true,
|
||||
'guardian_address' => 'Street 3, Street 4, City-2, State-2 112233, Country-2',
|
||||
"guardian_first_name" => nil,
|
||||
"guardian_last_name" => nil,
|
||||
"guardian_name_old" => nil,
|
||||
'guardian_phone' => '00 123 456 7890',
|
||||
'person_email' => 'email@email.com',
|
||||
'locale' => nil,
|
||||
'tagging_status' => 'pending',
|
||||
'contract_template_id' => nil,
|
||||
'applicable_medium_id' => nil,
|
||||
'applicable_medium_text' => '',
|
||||
'territory_id' => nil,
|
||||
'territory_text' => '',
|
||||
'term_id' => nil,
|
||||
'term_text' => '',
|
||||
'restriction_id' => nil,
|
||||
'restriction_text' => '',
|
||||
'signed_at' => nil,
|
||||
'internal_tag_list' => nil,
|
||||
'tag_list' => nil
|
||||
}
|
||||
end
|
||||
end
|
||||
44
spec/models/contract_template_spec.rb
Normal file
44
spec/models/contract_template_spec.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ContractTemplate do
|
||||
it_behaves_like 'an exploitable'
|
||||
|
||||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:project) }
|
||||
it { is_expected.to belong_to(:parent).optional }
|
||||
it { is_expected.to have_many(:duplicates) }
|
||||
it { is_expected.to have_many(:talent_releases).dependent(:restrict_with_error) }
|
||||
it { is_expected.to have_many(:appearance_releases).dependent(:restrict_with_error) }
|
||||
it { is_expected.to have_many(:location_releases).dependent(:restrict_with_error) }
|
||||
it { is_expected.to have_many(:material_releases).dependent(:restrict_with_error) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
it { is_expected.to validate_presence_of(:release_type) }
|
||||
end
|
||||
|
||||
describe '#fee' do
|
||||
it { is_expected.to monetize(:fee) }
|
||||
end
|
||||
|
||||
describe '#fee?' do
|
||||
it 'returns true when there is a fee amount' do
|
||||
fee_contract = build(:contract_template, fee: 500)
|
||||
no_fee_contract = build(:contract_template, fee: 0)
|
||||
|
||||
expect(fee_contract).to be_fee
|
||||
expect(no_fee_contract).not_to be_fee
|
||||
end
|
||||
end
|
||||
|
||||
describe '#duplicated?' do
|
||||
it 'returns true when there is a parent association' do
|
||||
contract_template = build(:contract_template, parent: build(:contract_template))
|
||||
|
||||
expect(contract_template).to be_duplicated
|
||||
end
|
||||
end
|
||||
end
|
||||
67
spec/models/directory_spec.rb
Normal file
67
spec/models/directory_spec.rb
Normal file
@@ -0,0 +1,67 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Directory, type: :model do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:project) }
|
||||
it { is_expected.to belong_to(:user) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
|
||||
describe "#name uniqueness validation" do
|
||||
subject { build(:directory) }
|
||||
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:project_id) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "enums" do
|
||||
it { is_expected.to define_enum_for(:permissions).with_values("Everyone": 0, "Account Managers & Project Managers": 1, "Account Managers Only": 2) }
|
||||
it { is_expected.to define_enum_for(:category).with_values("Other": 0, "Finance": 1, "Scripts": 2, "Call Sheets": 3, "Photos": 4, "Videos": 5) }
|
||||
end
|
||||
|
||||
describe "scopes" do
|
||||
it "should return directories in alphabetical order" do
|
||||
directory = create(:directory, name: "Payrolls", category: "Finance")
|
||||
directory_2 = create(:directory, name: "Actors", category: "Videos")
|
||||
|
||||
directories = Directory.order_by_name
|
||||
|
||||
# Directory one was created earlier than Directory 2
|
||||
expect(directory.created_at < directory_2.created_at).to be true
|
||||
|
||||
# Directories ordered in alphabetical order
|
||||
expect(directories.first.name).to eq "Actors"
|
||||
expect(directories.last.name).to eq "Payrolls"
|
||||
end
|
||||
|
||||
it "should return directories with permission 'Everyone'" do
|
||||
directory = create(:directory, name: "Payrolls", category: "Finance")
|
||||
directory_2 = create(:directory, :for_manager, name: "Actors", category: "Videos")
|
||||
|
||||
directories = Directory.for_associates
|
||||
|
||||
expect(directories).to include(directory)
|
||||
expect(directories).not_to include(directory_2)
|
||||
end
|
||||
|
||||
it "should return directories with permission 'Account Managers & Project Managers'" do
|
||||
directory = create(:directory, name: "Payrolls", category: "Finance")
|
||||
directory_2 = create(:directory, :for_manager, name: "Actors", category: "Videos")
|
||||
|
||||
directories = Directory.for_project_managers
|
||||
|
||||
expect(directories).to include(directory)
|
||||
expect(directories).to include(directory_2)
|
||||
end
|
||||
end
|
||||
|
||||
describe "search_files" do
|
||||
it "should return directories in alphabetical order" do
|
||||
directory = create(:directory, :with_files)
|
||||
results = directory.search_files('loc')
|
||||
|
||||
expect(results.first.filename).to eq "location_photo.png"
|
||||
end
|
||||
end
|
||||
end
|
||||
11
spec/models/download_spec.rb
Normal file
11
spec/models/download_spec.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Download, type: :model do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:project) }
|
||||
end
|
||||
|
||||
it "has an attached file" do
|
||||
expect(subject).to respond_to(:file)
|
||||
end
|
||||
end
|
||||
60
spec/models/duration_timecode_spec.rb
Normal file
60
spec/models/duration_timecode_spec.rb
Normal file
@@ -0,0 +1,60 @@
|
||||
require "spec_helper"
|
||||
require_relative "../../app/models/duration_timecode"
|
||||
|
||||
describe DurationTimecode do
|
||||
describe ".parse" do
|
||||
it "returns a new instance from a HH:MM:SS formatted string" do
|
||||
duration = described_class.parse("00:30:20")
|
||||
|
||||
expect(duration).to be_a(described_class)
|
||||
expect(duration.hours).to be_zero
|
||||
expect(duration.minutes).to eq(30)
|
||||
expect(duration.seconds).to eq(20)
|
||||
end
|
||||
|
||||
context "with an invalid format" do
|
||||
it "raises an error" do
|
||||
expect {
|
||||
described_class.parse("bad format")
|
||||
}.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".from_seconds" do
|
||||
it "returns a new instance from total seconds" do
|
||||
duration = described_class.from_seconds(3662)
|
||||
|
||||
expect(duration.hours).to eq(1)
|
||||
expect(duration.minutes).to eq(1)
|
||||
expect(duration.seconds).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_i" do
|
||||
it "returns the total number of seconds" do
|
||||
duration = described_class.parse("01:01:02")
|
||||
|
||||
expect(duration.to_i).to eq(3662)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_s" do
|
||||
it "returns a string in HH:MM:SS format" do
|
||||
duration = described_class.new(0, 15, 30)
|
||||
|
||||
expect(duration.to_s).to eq("00:15:30")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#+" do
|
||||
it "returns an instance representing the sum" do
|
||||
duration1 = described_class.new(0, 15, 40)
|
||||
duration2 = described_class.new(0, 3, 25)
|
||||
|
||||
sum = duration1 + duration2
|
||||
|
||||
expect(sum.to_s).to eq("00:19:05")
|
||||
end
|
||||
end
|
||||
end
|
||||
265
spec/models/edl_event_gateway_spec.rb
Normal file
265
spec/models/edl_event_gateway_spec.rb
Normal file
@@ -0,0 +1,265 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe EdlEventGateway do
|
||||
let(:files_for_request) do
|
||||
instance_double(FilesForRequest,
|
||||
file_object_name: "file_object_name",
|
||||
edl_file_object_name: "edl_file_object_name",
|
||||
aws_bucket_name: "aws_bucket_name",
|
||||
start_timecode_offset: nil,
|
||||
job_id: "video_analysis_uid",
|
||||
)
|
||||
end
|
||||
|
||||
describe "#edl_events" do
|
||||
it "filters edl events by channel_filter" do
|
||||
video_event = BrayniacAI::EdlParseResult.new({
|
||||
"channel" => "V",
|
||||
"start_time" => 0,
|
||||
"timecode_in" => "00:00:00:00",
|
||||
"timecode_out" => "00:00:01:00",
|
||||
"duration" => 1,
|
||||
"source_file_name" => "my_file.mp4",
|
||||
"clip_name" => "my_clip.mp4",
|
||||
"description" => "This is a great clip",
|
||||
"matches" => [1, 2],
|
||||
})
|
||||
audio_event = BrayniacAI::EdlParseResult.new({
|
||||
"channel" => "A1",
|
||||
"start_time" => 0,
|
||||
"timecode_in" => "00:00:00:00",
|
||||
"timecode_out" => "00:00:01:00",
|
||||
"duration" => 1,
|
||||
"source_file_name" => "my_file.mp3",
|
||||
"clip_name" => "my_clip.mp3",
|
||||
"description" => "This is a great clip",
|
||||
"matches" => [1, 2],
|
||||
})
|
||||
|
||||
allow(BrayniacAI::EdlParse).to receive(:create).and_return(
|
||||
BrayniacAI::EdlParse.new({ results: [video_event, audio_event] })
|
||||
)
|
||||
|
||||
edl_events = EdlEventGateway.new(
|
||||
files_for_request,
|
||||
"00:00:02:00",
|
||||
"00:00:02:00",
|
||||
channel_filter: "A",
|
||||
).edl_events
|
||||
|
||||
expect(edl_events.size).to eq(1)
|
||||
expect(edl_events).to include(EdlEvent.new({
|
||||
"channel" => "A1",
|
||||
"start_time" => 0,
|
||||
"timecode_in" => "00:00:00:00",
|
||||
"timecode_out" => "00:00:01:00",
|
||||
"duration" => 1,
|
||||
"source_file_name" => "my_file.mp3",
|
||||
"clip_name" => "my_clip.mp3",
|
||||
"description" => "This is a great clip",
|
||||
"matches" => [1, 2],
|
||||
}))
|
||||
end
|
||||
|
||||
describe "calling the API" do
|
||||
it "includes location information about the video file and EDL file" do
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
|
||||
allow(BrayniacAI::EdlParse).to receive(:create)
|
||||
|
||||
EdlEventGateway.new(
|
||||
files_for_request,
|
||||
"00:00:02:00",
|
||||
"00:00:02:00",
|
||||
).edl_events
|
||||
|
||||
expect(BrayniacAI::EdlParse).to have_received(:create).with(
|
||||
job_id: "video_analysis_uid",
|
||||
video_bucket_name: "aws_bucket_name",
|
||||
video_object_name: "file_object_name",
|
||||
edl_bucket_name: "aws_bucket_name",
|
||||
edl_object_name: "edl_file_object_name",
|
||||
timecode_start: "00:00:02:00",
|
||||
timecode_end: "00:00:02:00",
|
||||
collection: {},
|
||||
)
|
||||
end
|
||||
|
||||
it "includes collection when provided" do
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
|
||||
allow(BrayniacAI::EdlParse).to receive(:create)
|
||||
|
||||
EdlEventGateway.new(
|
||||
files_for_request,
|
||||
"00:00:02:00",
|
||||
"00:00:02:00",
|
||||
collection: { 1 => "source file name" },
|
||||
).edl_events
|
||||
|
||||
expect(BrayniacAI::EdlParse).to have_received(:create).with(
|
||||
job_id: "video_analysis_uid",
|
||||
video_bucket_name: "aws_bucket_name",
|
||||
video_object_name: "file_object_name",
|
||||
edl_bucket_name: "aws_bucket_name",
|
||||
edl_object_name: "edl_file_object_name",
|
||||
timecode_start: "00:00:02:00",
|
||||
timecode_end: "00:00:02:00",
|
||||
collection: { 1 => "source file name" },
|
||||
)
|
||||
end
|
||||
|
||||
it "includes start_timecode_offset when provided" do
|
||||
allow(files_for_request).to receive(:start_timecode_offset).and_return("start_timecode_offset")
|
||||
allow(BrayniacAI::EdlParse).to receive(:create)
|
||||
|
||||
EdlEventGateway.new(
|
||||
files_for_request,
|
||||
"00:00:02:00",
|
||||
"00:00:02:00",
|
||||
).edl_events
|
||||
|
||||
expect(BrayniacAI::EdlParse).to have_received(:create).with(
|
||||
job_id: "video_analysis_uid",
|
||||
video_bucket_name: "aws_bucket_name",
|
||||
video_object_name: "file_object_name",
|
||||
edl_bucket_name: "aws_bucket_name",
|
||||
edl_object_name: "edl_file_object_name",
|
||||
timecode_start: "00:00:02:00",
|
||||
timecode_end: "00:00:02:00",
|
||||
collection: {},
|
||||
edl_timecode_start: "start_timecode_offset",
|
||||
)
|
||||
end
|
||||
|
||||
it "does not include timecode_end, edl_timecode_start, job_id when given nil" do
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
|
||||
allow(BrayniacAI::EdlParse).to receive(:create)
|
||||
allow(files_for_request).to receive(:job_id).and_return(nil)
|
||||
|
||||
EdlEventGateway.new(
|
||||
files_for_request,
|
||||
"00:00:02:00",
|
||||
nil,
|
||||
collection: { 1 => "source file name" },
|
||||
).edl_events
|
||||
|
||||
expect(BrayniacAI::EdlParse).to have_received(:create).with(
|
||||
video_bucket_name: "aws_bucket_name",
|
||||
video_object_name: "file_object_name",
|
||||
edl_bucket_name: "aws_bucket_name",
|
||||
edl_object_name: "edl_file_object_name",
|
||||
timecode_start: "00:00:02:00",
|
||||
collection: { 1 => "source file name" },
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the collection of edl events from response" do
|
||||
edl_event = BrayniacAI::EdlParseResult.new({
|
||||
"channel" => "V",
|
||||
"start_time" => 0,
|
||||
"timecode_in" => "00:00:00:00",
|
||||
"timecode_out" => "00:00:01:00",
|
||||
"duration" => 1,
|
||||
"source_file_name" => "my_file.mp4",
|
||||
"clip_name" => "my_clip.mp4",
|
||||
"description" => "This is a great clip",
|
||||
"matches" => [1, 2],
|
||||
})
|
||||
|
||||
allow(BrayniacAI::EdlParse).to receive(:create).and_return(
|
||||
BrayniacAI::EdlParse.new({ results: [edl_event] })
|
||||
)
|
||||
|
||||
edl_events = EdlEventGateway.new(
|
||||
files_for_request,
|
||||
"00:00:02:00",
|
||||
"00:00:02:00",
|
||||
).edl_events
|
||||
|
||||
expect(edl_events.size).to eq(1)
|
||||
expect(edl_events).to include(EdlEvent.new({
|
||||
"channel" => "V",
|
||||
"start_time" => 0,
|
||||
"timecode_in" => "00:00:00:00",
|
||||
"timecode_out" => "00:00:01:00",
|
||||
"duration" => 1,
|
||||
"source_file_name" => "my_file.mp4",
|
||||
"clip_name" => "my_clip.mp4",
|
||||
"description" => "This is a great clip",
|
||||
"matches" => [1, 2],
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
describe "#edl_timecode_start" do
|
||||
it "returns edl_timecode_start from response" do
|
||||
allow(BrayniacAI::EdlParse).to receive(:create).and_return(BrayniacAI::EdlParse.new(edl_timecode_start: "edl_timecode_start"))
|
||||
|
||||
expect(described_class.new(
|
||||
files_for_request,
|
||||
"00:00:00:00",
|
||||
"00:00:00:00"
|
||||
).edl_timecode_start).to eq "edl_timecode_start"
|
||||
end
|
||||
|
||||
context "when response nil" do
|
||||
it "returns edl_timecode_start from response" do
|
||||
allow(BrayniacAI::EdlParse).to receive(:create).and_return(nil)
|
||||
|
||||
expect(described_class.new(
|
||||
files_for_request,
|
||||
"00:00:00:00",
|
||||
"00:00:00:00"
|
||||
).edl_timecode_start).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fps" do
|
||||
it "returns fps from response" do
|
||||
allow(BrayniacAI::EdlParse).to receive(:create).and_return(BrayniacAI::EdlParse.new(fps: 29.97))
|
||||
|
||||
expect(described_class.new(
|
||||
files_for_request,
|
||||
"00:00:00:00",
|
||||
"00:00:00:00"
|
||||
).fps).to eq 29.97
|
||||
end
|
||||
|
||||
context "when response nil" do
|
||||
it "returns nil" do
|
||||
allow(BrayniacAI::EdlParse).to receive(:create).and_return(nil)
|
||||
|
||||
expect(described_class.new(
|
||||
files_for_request,
|
||||
"00:00:00:00",
|
||||
"00:00:00:00"
|
||||
).fps).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#edl_offset_seconds" do
|
||||
it "returns edl_offset_seconds from response" do
|
||||
allow(BrayniacAI::EdlParse).to receive(:create).and_return(BrayniacAI::EdlParse.new(edl_offset_seconds: 100))
|
||||
|
||||
expect(described_class.new(
|
||||
files_for_request,
|
||||
"00:00:00:00",
|
||||
"00:00:00:00"
|
||||
).edl_offset_seconds).to eq 100
|
||||
end
|
||||
|
||||
context "when response nil" do
|
||||
it "returns edl_offset_seconds from response" do
|
||||
allow(BrayniacAI::EdlParse).to receive(:create).and_return(nil)
|
||||
|
||||
expect(described_class.new(
|
||||
files_for_request,
|
||||
"00:00:00:00",
|
||||
"00:00:00:00"
|
||||
).edl_offset_seconds).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,138 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module AudioReports
|
||||
RSpec.describe AudioConfirmationData do
|
||||
let(:audio_confirmation) do
|
||||
build(:audio_confirmation,
|
||||
music_type: "Vocal",
|
||||
music_category: "Feature",
|
||||
title: "title",
|
||||
source_file_name: "source_file_name",
|
||||
)
|
||||
end
|
||||
|
||||
subject { described_class.new(audio_confirmation) }
|
||||
|
||||
describe "#music_type" do
|
||||
it "returns first letter of music_type" do
|
||||
expect(subject.music_type).to eq "V"
|
||||
end
|
||||
|
||||
context "when music_type nil" do
|
||||
before :each do
|
||||
audio_confirmation.music_type = nil
|
||||
end
|
||||
|
||||
it "returns empty string" do
|
||||
expect(subject.music_type).to eq ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#music_category" do
|
||||
it "returns first letter of music_category" do
|
||||
expect(subject.music_category).to eq "F"
|
||||
end
|
||||
|
||||
context "when music_category nil" do
|
||||
before :each do
|
||||
audio_confirmation.music_category = nil
|
||||
end
|
||||
|
||||
it "returns empty string" do
|
||||
expect(subject.music_category).to eq ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#title_and_source_file_name" do
|
||||
it "returns title_and_source_file_name and source filename separated by dash" do
|
||||
expect(subject.title_and_source_file_name).to eq("title - source_file_name")
|
||||
end
|
||||
|
||||
context "when source filename is blank" do
|
||||
it "returns title_and_source_file_name alone" do
|
||||
audio_confirmation.source_file_name = nil
|
||||
|
||||
expect(subject.title_and_source_file_name).to eq("title")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#origin" do
|
||||
context "for library music" do
|
||||
let(:audio_confirmation) { build(:audio_confirmation, :library) }
|
||||
|
||||
it "returns 'Production Library (Non-affiliated)'" do
|
||||
expect(subject.origin).to eq("Production Library (Non-affiliated)")
|
||||
end
|
||||
end
|
||||
|
||||
context "for original music" do
|
||||
let(:audio_confirmation) { build(:audio_confirmation, :original) }
|
||||
|
||||
it "returns 'Commissioned'" do
|
||||
expect(subject.origin).to eq("Commissioned")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#composers_with_split" do
|
||||
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, BMI, 50%") }
|
||||
|
||||
it "includes name, affiliation, and percentage split" do
|
||||
expect(subject.composers_with_split).to eq "John Doe (BMI) 50.0%"
|
||||
end
|
||||
|
||||
context "when there are co-writers " do
|
||||
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, Jane Doe, BMI, 50%") }
|
||||
|
||||
it "includes both names" do
|
||||
expect(subject.composers_with_split).to eq "John Doe, Jane Doe (BMI) 50.0%"
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are multiple composers" do
|
||||
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, BMI, 50% | Jane Doe, Universal, 50%") }
|
||||
|
||||
it "includes both composers separated by a newline" do
|
||||
expect(subject.composers_with_split).to eq "John Doe (BMI) 50.0%\n Jane Doe (Universal) 50.0%"
|
||||
end
|
||||
end
|
||||
|
||||
context "when there is a cae number" do
|
||||
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, Jane Doe, BMI, 50%, $cae:abc123 | James Doe, Universal, 50%, $cae:def456") }
|
||||
|
||||
it "does not include the cae number" do
|
||||
expect(subject.composers_with_split).to eq "John Doe, Jane Doe (BMI) 50.0%\n James Doe (Universal) 50.0%"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#composers_cae_numbers" do
|
||||
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, BMI, 50%, $cae:abc123") }
|
||||
|
||||
it "includes cae number" do
|
||||
expect(subject.composers_cae_numbers).to eq("abc123")
|
||||
end
|
||||
|
||||
context "when there are multiple composers" do
|
||||
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, BMI, 50%, $cae:abc123 | Jane Doe, Universal, 50%, $cae:def456") }
|
||||
|
||||
it "includes all cae numbers separated by a newline" do
|
||||
expect(subject.composers_cae_numbers).to eq("abc123\ndef456")
|
||||
end
|
||||
end
|
||||
|
||||
context "when cae numbers are not present" do
|
||||
let(:audio_confirmation) { build(:audio_confirmation, composer_info: "John Doe, BMI, 50%") }
|
||||
|
||||
it "returns an empty string" do
|
||||
expect(subject.composers_cae_numbers).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,69 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module AudioReports
|
||||
RSpec.describe BrayInnovationGroupMusicCueReport do
|
||||
let(:video) { create(:video) }
|
||||
|
||||
subject { described_class.new(video) }
|
||||
|
||||
describe "#to_xls" do
|
||||
it "builds report" do
|
||||
package = instance_double(Axlsx::Package)
|
||||
workbook = instance_double(Axlsx::Workbook)
|
||||
stream = double(:stream, read: "my-report")
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(BrayInnovationGroupMusicCueSheet).to receive(:build)
|
||||
|
||||
create(:audio_confirmation, :library, video: video)
|
||||
create(:audio_confirmation, :original, video: video)
|
||||
|
||||
result = subject.to_xls
|
||||
|
||||
expect(package).to have_received(:to_stream)
|
||||
expect(BrayInnovationGroupMusicCueSheet).to have_received(:build).with(
|
||||
workbook,
|
||||
[instance_of(AudioConfirmationData), instance_of(AudioConfirmationData)],
|
||||
instance_of(BrayInnovationGroupMusicCueHeaderData)
|
||||
)
|
||||
expect(stream).to have_received(:read)
|
||||
expect(result).to eq("my-report")
|
||||
end
|
||||
|
||||
it "sorts audio data by ascending timecode_in" do
|
||||
package = instance_double(Axlsx::Package)
|
||||
workbook = instance_double(Axlsx::Workbook)
|
||||
stream = double(:stream, read: "my-report")
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(BrayInnovationGroupMusicCueSheet).to receive(:build)
|
||||
|
||||
earlier = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:02")
|
||||
earliest = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:01")
|
||||
early = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:03")
|
||||
|
||||
subject.to_xls
|
||||
|
||||
expect(BrayInnovationGroupMusicCueSheet).to have_received(:build).with(
|
||||
workbook,
|
||||
[
|
||||
AudioConfirmationData.new(earliest),
|
||||
AudioConfirmationData.new(earlier),
|
||||
AudioConfirmationData.new(early),
|
||||
],
|
||||
instance_of(BrayInnovationGroupMusicCueHeaderData)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#filename" do
|
||||
it "returns video filename with 'big-cue-sheet'" do
|
||||
expect(subject.filename).to eq "video_file-mp4_big-cue-sheet.xlsx"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,176 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module AudioReports
|
||||
RSpec.describe BrayInnovationGroupMusicCueSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
subject { described_class.new(workbook) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'BiG Music Cue Sheet'" do
|
||||
expect(subject.title).to eq "BiG Music Cue Sheet"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds headers and data to given sheet" do
|
||||
sheet = instance_double(Axlsx::Worksheet)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
video = create(:video,
|
||||
name: "video name",
|
||||
project: build(:project,
|
||||
producer_name: "company name",
|
||||
producer_address: "company address",
|
||||
),
|
||||
)
|
||||
original_confirmation = create(:audio_confirmation, :original,
|
||||
video: video,
|
||||
title: "title_1",
|
||||
source_file_name: "filename_1",
|
||||
timecode_in: "01:00:00:00",
|
||||
timecode_out: "01:05:00:00",
|
||||
duration: "00:05:00",
|
||||
music_type: "Vocal",
|
||||
music_category: "Background",
|
||||
composer_info: "composer1, affiliation, 50%|composer2, affiliation, 50%",
|
||||
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
|
||||
)
|
||||
library_confirmation = create(:audio_confirmation, :library,
|
||||
video: video,
|
||||
title: "title_2",
|
||||
source_file_name: "filename_2",
|
||||
timecode_in: "01:00:00:00",
|
||||
timecode_out: "01:05:00:00",
|
||||
duration: "00:05:00",
|
||||
music_type: "Vocal",
|
||||
music_category: "Background",
|
||||
composer_info: "composer1, affiliation, 50%|composer2, affiliation, 50%",
|
||||
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
|
||||
)
|
||||
header_data = BrayInnovationGroupMusicCueHeaderData.new(video)
|
||||
data = [AudioConfirmationData.new(original_confirmation), AudioConfirmationData.new(library_confirmation)]
|
||||
|
||||
described_class.new(workbook, data, header_data).fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with(["TITLE", "video name"])
|
||||
expect(sheet).to have_received(:add_row).with(["COMPANY NAME", "company name"])
|
||||
expect(sheet).to have_received(:add_row).with(["ADDRESS", "company address"])
|
||||
expect(sheet).to have_received(:add_row).with(["LENGTH", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["TYPE", ""])
|
||||
expect(sheet).to have_received(:add_row).with(no_args)
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"Cue #",
|
||||
"Cue Title",
|
||||
"Composer(s)/Affiliation",
|
||||
"%",
|
||||
"Publisher(s)/Affiliation",
|
||||
"%",
|
||||
"Use",
|
||||
"",
|
||||
"In Time",
|
||||
"Out Time",
|
||||
"Duration",
|
||||
])
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"I = Instr.\nV = Vocal",
|
||||
"B = Bckgrnd\nF = Feature\nT = Theme",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
])
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"",
|
||||
"title_1 - filename_1",
|
||||
"composer1 (affiliation)\ncomposer2 (affiliation)",
|
||||
"50.0\n50.0",
|
||||
"publisher1 (affiliation)\npublisher2 (affiliation)",
|
||||
"50.0\n50.0",
|
||||
"V",
|
||||
"B",
|
||||
"01:00:00:00",
|
||||
"01:05:00:00",
|
||||
"00:05:00",
|
||||
])
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"",
|
||||
"title_2 - filename_2",
|
||||
"composer1 (affiliation)\ncomposer2 (affiliation)",
|
||||
"50.0\n50.0",
|
||||
"publisher1 (affiliation)\npublisher2 (affiliation)",
|
||||
"50.0\n50.0",
|
||||
"V",
|
||||
"B",
|
||||
"01:00:00:00",
|
||||
"01:05:00:00",
|
||||
"00:05:00",
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets column widths" do
|
||||
sheet = instance_double(Axlsx::Worksheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths).with(15, 40, 20, 10, 20, 10, 20, 20, 15, 15, 15)
|
||||
expect(sheet).to have_received(:merge_cells).with("G7:H7")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
expect(sheet).to receive(:add_style).with("A1:A5",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :wrap_text => true },
|
||||
sz: 12,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"B1:B5",
|
||||
{
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :wrap_text => true, :horizontal => :left },
|
||||
sz: 10,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"A7:K7",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
|
||||
sz: 8,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).at_least(1).with("A9:K10",
|
||||
{
|
||||
border: { style: :thick, color: "000000" },
|
||||
alignment: { wrap_text: true },
|
||||
sz: 10
|
||||
}
|
||||
)
|
||||
|
||||
described_class.new(workbook, ["data1", "data2"]).style(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,69 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module AudioReports
|
||||
RSpec.describe DiscoveryMusicCueReport do
|
||||
let(:video) { create(:video) }
|
||||
|
||||
subject { described_class.new(video) }
|
||||
|
||||
describe "#to_xls" do
|
||||
it "builds report" do
|
||||
package = instance_double(Axlsx::Package)
|
||||
workbook = instance_double(Axlsx::Workbook)
|
||||
stream = double(:stream, read: "my-report")
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(DiscoveryMusicCueSheet).to receive(:build)
|
||||
|
||||
create(:audio_confirmation, :original, video: video)
|
||||
create(:audio_confirmation, :library, video: video)
|
||||
|
||||
result = subject.to_xls
|
||||
|
||||
expect(package).to have_received(:to_stream)
|
||||
expect(DiscoveryMusicCueSheet).to have_received(:build).with(
|
||||
workbook,
|
||||
[instance_of(AudioConfirmationData), instance_of(AudioConfirmationData)],
|
||||
instance_of(DiscoveryMusicCueHeaderData)
|
||||
)
|
||||
expect(stream).to have_received(:read)
|
||||
expect(result).to eq("my-report")
|
||||
end
|
||||
|
||||
it "sorts audio data by ascending timecode_in" do
|
||||
package = instance_double(Axlsx::Package)
|
||||
workbook = instance_double(Axlsx::Workbook)
|
||||
stream = double(:stream, read: "my-report")
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(DiscoveryMusicCueSheet).to receive(:build)
|
||||
|
||||
earlier = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:02")
|
||||
earliest = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:01")
|
||||
early = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:03")
|
||||
|
||||
subject.to_xls
|
||||
|
||||
expect(DiscoveryMusicCueSheet).to have_received(:build).with(
|
||||
workbook,
|
||||
[
|
||||
AudioConfirmationData.new(earliest),
|
||||
AudioConfirmationData.new(earlier),
|
||||
AudioConfirmationData.new(early),
|
||||
],
|
||||
instance_of(DiscoveryMusicCueHeaderData)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#filename" do
|
||||
it "returns video filename with 'discovery-cue-sheet'" do
|
||||
expect(subject.filename).to eq "video_file-mp4_discovery-cue-sheet.xlsx"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,195 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module AudioReports
|
||||
RSpec.describe DiscoveryMusicCueSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
subject { described_class.new(workbook) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Discovery Music Cue Sheet'" do
|
||||
expect(subject.title).to eq "Discovery Music Cue Sheet"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds headers and data to given sheet for both types of audio confirmations" do
|
||||
sheet = instance_double(Axlsx::Worksheet)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
project = create(:project, client_name: "client_name", producer_name: "producer_name")
|
||||
video = create(:video, project: project, number: 42, name: "video_name")
|
||||
header_data = DiscoveryMusicCueHeaderData.new(video)
|
||||
data = [
|
||||
AudioConfirmationData.new(
|
||||
build(:audio_confirmation,
|
||||
timecode_in: "timecode_in_1",
|
||||
title: "title_1",
|
||||
catalog: "catalog_1",
|
||||
duration: "duration_1",
|
||||
music_type: "music_type_1",
|
||||
music_category: "music_category_1",
|
||||
composer_info: "composer_info_1",
|
||||
publisher_info: "publisher_info_1",
|
||||
source_file_name: "source_file_name_1",
|
||||
)
|
||||
),
|
||||
AudioConfirmationData.new(
|
||||
build(:audio_confirmation,
|
||||
timecode_in: "timecode_in_2",
|
||||
title: "title_2",
|
||||
catalog: "catalog_2",
|
||||
duration: "duration_2",
|
||||
music_type: "music_type_2",
|
||||
music_category: "music_category_2",
|
||||
composer_info: "composer_info_2",
|
||||
publisher_info: "publisher_info_2",
|
||||
source_file_name: "source_file_name_2",
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
described_class.new(workbook, data, header_data).fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with(["Original Production Title", "video_name", "Original Series Title", "", "Broadcaster", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["Alternative Production Title", "", "Alternative Series Title", "", "Production Company", "producer_name"])
|
||||
expect(sheet).to have_received(:add_row).with(["Local Production Title", "", "Local Series Title", "", "", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["Working Production Title", "", "Working Series Title", "", "Production Number", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["Version Production Title", "", "Version Series Title", "", "Director", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["Episode No.", "42", "Season No.", "", "Production Parent Identifier", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["Year", "", "Country", "", "Soundmouse Legacy Identifier", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["Duration", "", "Type", "", "Production ID", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["First Transmission", "", "Source", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["Product Name", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["Client Name", "client_name"])
|
||||
expect(sheet).to have_received(:add_row).with(["Narrative", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["End Line", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["Clock Number", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["ISAN", ""])
|
||||
expect(sheet).to have_received(:add_row).with(no_args)
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"No.",
|
||||
"Timecode",
|
||||
"Title",
|
||||
"Music Origin",
|
||||
"Use (Theme/Description)",
|
||||
"Interested Parties",
|
||||
"Identifiers",
|
||||
"Duration",
|
||||
])
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
1,
|
||||
"timecode_in_1",
|
||||
"title_1 - source_file_name_1",
|
||||
"catalog_1",
|
||||
"music_type_1 music_category_1",
|
||||
"Composers:\ncomposer_info_1\nPublishers:\npublisher_info_1",
|
||||
"",
|
||||
"duration_1",
|
||||
])
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
2,
|
||||
"timecode_in_2",
|
||||
"title_2 - source_file_name_2",
|
||||
"catalog_2",
|
||||
"music_type_2 music_category_2",
|
||||
"Composers:\ncomposer_info_2\nPublishers:\npublisher_info_2",
|
||||
"",
|
||||
"duration_2",
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets column widths" do
|
||||
sheet = instance_double(Axlsx::Worksheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths).with(20, 20, 40, 20, 20, 20, 20, 20)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
expect(sheet).to receive(:add_style).with("A1:A15",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :wrap_text => true },
|
||||
sz: 12,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with("C1:C9",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :wrap_text => true },
|
||||
sz: 12,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with("E1:E8",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :wrap_text => true },
|
||||
sz: 12,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"B1:B15",
|
||||
{
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :wrap_text => true, :horizontal => :left },
|
||||
sz: 10,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"D1:D9",
|
||||
{
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :wrap_text => true, :horizontal => :left },
|
||||
sz: 10,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"F1:F8",
|
||||
{
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :wrap_text => true, :horizontal => :left },
|
||||
sz: 10,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"A17:H17",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
|
||||
sz: 8,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).at_least(1).with(
|
||||
"A18:H19",
|
||||
{
|
||||
border: { style: :thick, color: "000000" },
|
||||
alignment: { wrap_text: true },
|
||||
sz: 10
|
||||
}
|
||||
)
|
||||
|
||||
described_class.new(workbook, ["data1", "data2"]).style(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,67 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module AudioReports
|
||||
RSpec.describe NatGeoMusicCueSheet do
|
||||
let(:video) { create(:video) }
|
||||
|
||||
subject { described_class.new(video) }
|
||||
|
||||
describe "#to_xls" do
|
||||
it "builds report" do
|
||||
package = instance_double(Axlsx::Package)
|
||||
workbook = instance_double(Axlsx::Workbook)
|
||||
stream = double(:stream, read: "my-report")
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(NatGeoMusicCueSheets::MainSheet).to receive(:build)
|
||||
|
||||
create(:audio_confirmation, :original, video: video)
|
||||
create(:audio_confirmation, :library, video: video)
|
||||
|
||||
result = subject.to_xls
|
||||
|
||||
expect(package).to have_received(:to_stream)
|
||||
expect(NatGeoMusicCueSheets::MainSheet).to have_received(:build).with(
|
||||
workbook,
|
||||
[instance_of(AudioConfirmationData), instance_of(AudioConfirmationData)],
|
||||
)
|
||||
expect(stream).to have_received(:read)
|
||||
expect(result).to eq("my-report")
|
||||
end
|
||||
|
||||
it "sorts audio data by ascending timecode_in" do
|
||||
package = instance_double(Axlsx::Package)
|
||||
workbook = instance_double(Axlsx::Workbook)
|
||||
stream = double(:stream, read: "my-report")
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(NatGeoMusicCueSheets::MainSheet).to receive(:build)
|
||||
|
||||
earlier = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:02")
|
||||
earliest = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:01")
|
||||
early = create(:audio_confirmation, :library, video: video, timecode_in: "00:00:00:03")
|
||||
|
||||
subject.to_xls
|
||||
|
||||
expect(NatGeoMusicCueSheets::MainSheet).to have_received(:build).with(
|
||||
workbook,
|
||||
[
|
||||
AudioConfirmationData.new(earliest),
|
||||
AudioConfirmationData.new(earlier),
|
||||
AudioConfirmationData.new(early),
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#filename" do
|
||||
it "returns video filename with 'discovery-cue-sheet'" do
|
||||
expect(subject.filename).to eq "video_file-mp4_music-cue-sheet.xlsx"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,129 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module AudioReports
|
||||
module NatGeoMusicCueSheets
|
||||
RSpec.describe MainSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
subject { described_class.new(workbook) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns the title of the sheet" do
|
||||
expect(subject.title).to eq "Nat Geo Music Cue Sheet"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds headers and data to given sheet for both types of audio confirmations" do
|
||||
sheet = instance_double(Axlsx::Worksheet)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
video = create(:video)
|
||||
header_data = video
|
||||
data = [
|
||||
AudioConfirmationData.new(
|
||||
build(:audio_confirmation,
|
||||
:library,
|
||||
timecode_in: "timecode_in_1",
|
||||
timecode_out: "timecode_out_1",
|
||||
title: "title_1",
|
||||
catalog: "catalog_1",
|
||||
duration: "00:02:30",
|
||||
music_type: "music_type_1",
|
||||
music_category: "music_category_1",
|
||||
composer_info: "composer1, affiliation, 50%|composer2, affiliation, 50%",
|
||||
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
|
||||
source_file_name: "source_file_name_1",
|
||||
)
|
||||
),
|
||||
AudioConfirmationData.new(
|
||||
build(:audio_confirmation,
|
||||
:original,
|
||||
timecode_in: "timecode_in_2",
|
||||
timecode_out: "timecode_out_2",
|
||||
title: "title_2",
|
||||
catalog: "catalog_2",
|
||||
duration: "00:03:50",
|
||||
music_type: "music_type_2",
|
||||
music_category: "music_category_2",
|
||||
composer_info: "composer1, affiliation, 50%|composer2, affiliation, 50%",
|
||||
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
|
||||
source_file_name: "source_file_name_2",
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
described_class.new(workbook, data, header_data).fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"No.",
|
||||
"Title",
|
||||
"In",
|
||||
"Out",
|
||||
"Composer",
|
||||
"Publisher",
|
||||
"Record Label / Library",
|
||||
"Music Origin",
|
||||
"Use",
|
||||
"Duration",
|
||||
])
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
1,
|
||||
"title_1 - source_file_name_1",
|
||||
"timecode_in_1",
|
||||
"timecode_out_1",
|
||||
"composer1 (affiliation) 50.0%\ncomposer2 (affiliation) 50.0%",
|
||||
"publisher1 (affiliation) 50.0%\npublisher2 (affiliation) 50.0%",
|
||||
"catalog_1",
|
||||
"Production Library (Non-affiliated)",
|
||||
"music_type_1 music_category_1",
|
||||
"00:02:30",
|
||||
])
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
2,
|
||||
"title_2 - source_file_name_2",
|
||||
"timecode_in_2",
|
||||
"timecode_out_2",
|
||||
"composer1 (affiliation) 50.0%\ncomposer2 (affiliation) 50.0%",
|
||||
"publisher1 (affiliation) 50.0%\npublisher2 (affiliation) 50.0%",
|
||||
"catalog_2",
|
||||
"Commissioned",
|
||||
"music_type_2 music_category_2",
|
||||
"00:03:50",
|
||||
])
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"", "", "", "", "", "", "", "", "Total Music Duration:", "00:06:20"
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets column widths and merges cells" do
|
||||
sheet = instance_double(Axlsx::Worksheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths)
|
||||
expect(sheet).to have_received(:merge_cells).at_least(1).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_style)
|
||||
|
||||
described_class.new(workbook, ["data1", "data2"]).style(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_style).at_least(1).times
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,87 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module AudioReports
|
||||
RSpec.describe NatGeoOriginalMusicLog do
|
||||
let(:video) { create(:video) }
|
||||
|
||||
subject { described_class.new(video) }
|
||||
|
||||
describe "#to_xls" do
|
||||
it "builds report" do
|
||||
package = instance_double(Axlsx::Package)
|
||||
workbook = instance_double(Axlsx::Workbook)
|
||||
stream = double(:stream, read: "my-report")
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(NatGeoOriginalMusicLogs::MainSheet).to receive(:build)
|
||||
|
||||
create(:audio_confirmation, :original, video: video)
|
||||
create(:audio_confirmation, :original, video: video)
|
||||
|
||||
result = subject.to_xls
|
||||
|
||||
expect(package).to have_received(:to_stream)
|
||||
expect(NatGeoOriginalMusicLogs::MainSheet).to have_received(:build).with(
|
||||
workbook,
|
||||
[instance_of(AudioConfirmationData), instance_of(AudioConfirmationData)],
|
||||
)
|
||||
expect(stream).to have_received(:read)
|
||||
expect(result).to eq("my-report")
|
||||
end
|
||||
|
||||
it "sorts audio data by ascending timecode_in" do
|
||||
package = instance_double(Axlsx::Package)
|
||||
workbook = instance_double(Axlsx::Workbook)
|
||||
stream = double(:stream, read: "my-report")
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(NatGeoOriginalMusicLogs::MainSheet).to receive(:build)
|
||||
|
||||
earlier = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:02")
|
||||
earliest = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:01")
|
||||
early = create(:audio_confirmation, :original, video: video, timecode_in: "00:00:00:03")
|
||||
|
||||
subject.to_xls
|
||||
|
||||
expect(NatGeoOriginalMusicLogs::MainSheet).to have_received(:build).with(
|
||||
workbook,
|
||||
[
|
||||
AudioConfirmationData.new(earliest),
|
||||
AudioConfirmationData.new(earlier),
|
||||
AudioConfirmationData.new(early),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
it "only includes original music" do
|
||||
package = instance_double(Axlsx::Package)
|
||||
workbook = instance_double(Axlsx::Workbook)
|
||||
stream = double(:stream, read: "my-report")
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(NatGeoOriginalMusicLogs::MainSheet).to receive(:build)
|
||||
|
||||
original = create(:audio_confirmation, :original, video: video)
|
||||
library = create(:audio_confirmation, :library, video: video)
|
||||
|
||||
subject.to_xls
|
||||
|
||||
expect(NatGeoOriginalMusicLogs::MainSheet).to have_received(:build).with(
|
||||
workbook,
|
||||
[AudioConfirmationData.new(original)]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#filename" do
|
||||
it "returns video filename with 'discovery-cue-sheet'" do
|
||||
expect(subject.filename).to eq "video_file-mp4_original-music-log.xlsx"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,85 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module AudioReports
|
||||
module NatGeoOriginalMusicLogs
|
||||
RSpec.describe MainSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
subject { described_class.new(workbook) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns the title of the sheet" do
|
||||
expect(subject.title).to eq "Nat Geo Original Music Log"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds headers and data to given sheet for both types of audio confirmations" do
|
||||
sheet = instance_double(Axlsx::Worksheet)
|
||||
allow(sheet).to receive(:add_row)
|
||||
allow(BigMediaTime).to receive(:time_zone_now).and_return(DateTime.new(2019,10,9))
|
||||
|
||||
video = create(:video)
|
||||
header_data = video
|
||||
data = [
|
||||
AudioConfirmationData.new(
|
||||
build(:audio_confirmation,
|
||||
:original,
|
||||
title: "title_1",
|
||||
composer_info: "composer1a, composer1b, affiliation, 50%, $cae:cae123|composer2, affiliation, 50%, $cae:cae456",
|
||||
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
|
||||
source_file_name: "source_file_name_1",
|
||||
)
|
||||
),
|
||||
]
|
||||
|
||||
described_class.new(workbook, data, header_data).fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"10/09/19", "", "", ""
|
||||
])
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"CUE TITLE",
|
||||
"COMPOSER(S), % SPLIT & PRO",
|
||||
"COMPOSER CAE/IPI#",
|
||||
"PUBLISHER(S), % SPLIT & PRO",
|
||||
])
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"title_1 - source_file_name_1",
|
||||
"composer1a, composer1b (affiliation) 50.0%\ncomposer2 (affiliation) 50.0%",
|
||||
"cae123\ncae456",
|
||||
"publisher1 (affiliation) 50.0%\npublisher2 (affiliation) 50.0%",
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets column widths and merge cells" do
|
||||
sheet = instance_double(Axlsx::Worksheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths)
|
||||
expect(sheet).to have_received(:merge_cells).at_least(1).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_style)
|
||||
|
||||
described_class.new(workbook, ["data1", "data2"]).style(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_style).at_least(1).times
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,91 @@
|
||||
require 'rails_helper'
|
||||
|
||||
module ExcelReports
|
||||
module GraphicReports
|
||||
RSpec.describe DiscoveryGfxCueList do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
describe '#to_xls' do
|
||||
it 'builds xls file' do
|
||||
graphics_element = create(:graphics_element)
|
||||
video = create(:video, graphics_elements: [graphics_element], project: project)
|
||||
package = double(:package)
|
||||
workbook = double(:workbook)
|
||||
stream = double(:stream)
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
|
||||
expect(DiscoveryGfxCueLists::TextedElementsSheet).to receive(:build).with(
|
||||
workbook,
|
||||
[
|
||||
DiscoveryGfxCueList::GraphicsElementsData.new(
|
||||
"some text",
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
],
|
||||
DiscoveryGfxCueList::GraphicsElementsHeaderData.new(
|
||||
nil,
|
||||
nil,
|
||||
"My Client",
|
||||
"My Team",
|
||||
)
|
||||
)
|
||||
expect(package).to receive(:to_stream).and_return(stream)
|
||||
expect(stream).to receive(:read)
|
||||
|
||||
described_class.new(video).to_xls
|
||||
end
|
||||
|
||||
it 'sorts the element data by timecode' do
|
||||
graphics_elements = [
|
||||
build(:graphics_element, timecode_in: "00:00:10:00"),
|
||||
build(:graphics_element, timecode_in: "00:00:05:00"),
|
||||
build(:graphics_element, timecode_in: nil )
|
||||
]
|
||||
video = create(:video, graphics_elements: graphics_elements, project: project)
|
||||
package = double(:package)
|
||||
workbook = double(:workbook)
|
||||
stream = double(:stream)
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(stream).to receive(:read)
|
||||
|
||||
expect(DiscoveryGfxCueLists::TextedElementsSheet).to receive(:build).with(
|
||||
workbook,
|
||||
[
|
||||
DiscoveryGfxCueList::GraphicsElementsData.new(
|
||||
"some text",
|
||||
"00:00:05:00",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DiscoveryGfxCueList::GraphicsElementsData.new(
|
||||
"some text",
|
||||
"00:00:10:00",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
DiscoveryGfxCueList::GraphicsElementsData.new(
|
||||
"some text",
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
],
|
||||
DiscoveryGfxCueList::GraphicsElementsHeaderData.new(
|
||||
nil,
|
||||
nil,
|
||||
"My Client",
|
||||
"My Team",
|
||||
)
|
||||
)
|
||||
|
||||
described_class.new(video).to_xls
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,73 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module GraphicReports
|
||||
module DiscoveryGfxCueLists
|
||||
RSpec.describe TextedElementsSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
it_behaves_like "a worksheet" do
|
||||
subject { described_class.new(workbook) }
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Texted Elements List'" do
|
||||
expect(described_class.new(workbook).title).to eq "Texted Elements List"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets sheet column widths to 60, 20, 20" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
expect(sheet).to receive(:column_widths).with(60, 20, 20)
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
expect(sheet).to receive(:add_style).with("A1", { b: true }, { sz: 12 })
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"A9:D9",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
|
||||
sz: 8,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with("A3:A7",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :wrap_text => true },
|
||||
sz: 12,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"B3:B7",
|
||||
{
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :wrap_text => true, :horizontal => :left },
|
||||
sz: 10,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).at_least(1).with("A10:D11",
|
||||
{
|
||||
border: { style: :thick, color: "000000" },
|
||||
alignment: { wrap_text: true },
|
||||
sz: 10
|
||||
}
|
||||
)
|
||||
|
||||
described_class.new(workbook, ["data1", "data2"]).style(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,53 @@
|
||||
require 'rails_helper'
|
||||
|
||||
module ExcelReports
|
||||
module GraphicReports
|
||||
RSpec.describe NatGeoTextGraphicsLog do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
describe '#to_xls' do
|
||||
it 'builds xls file' do
|
||||
graphics_element = create(:graphics_element)
|
||||
video = create(:video, graphics_elements: [graphics_element], project: project)
|
||||
package = double(:package)
|
||||
workbook = double(:workbook)
|
||||
stream = double(:stream)
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
|
||||
expect(NatGeoTextGraphicsLogs::InternalProgramGfxLogSheet).to receive(:build).with(
|
||||
workbook,
|
||||
[graphics_element],
|
||||
video,
|
||||
)
|
||||
expect(package).to receive(:to_stream).and_return(stream)
|
||||
expect(stream).to receive(:read)
|
||||
|
||||
described_class.new(video).to_xls
|
||||
end
|
||||
|
||||
it 'sorts the element data by timecode' do
|
||||
graphics_elements = [
|
||||
build(:graphics_element, timecode_in: "00:00:10:00"),
|
||||
build(:graphics_element, timecode_in: "00:00:05:00"),
|
||||
build(:graphics_element, timecode_in: nil )
|
||||
]
|
||||
video = create(:video, graphics_elements: graphics_elements, project: project)
|
||||
package = double(:package)
|
||||
workbook = double(:workbook)
|
||||
stream = double(:stream)
|
||||
allow(Axlsx::Package).to receive(:new).and_return(package)
|
||||
allow(package).to receive(:workbook).and_return(workbook)
|
||||
allow(package).to receive(:to_stream).and_return(stream)
|
||||
allow(stream).to receive(:read)
|
||||
|
||||
expect(NatGeoTextGraphicsLogs::InternalProgramGfxLogSheet).to receive(:build).with(
|
||||
workbook, [graphics_elements.second, graphics_elements.first, graphics_elements.last], video,
|
||||
)
|
||||
|
||||
described_class.new(video).to_xls
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,66 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module GraphicReports
|
||||
module NatGeoTextGraphicsLogs
|
||||
RSpec.describe InternalProgramGfxLogSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
let(:video) { build(:video, name: "My Video", number: 10) }
|
||||
let(:graphics_element) do
|
||||
build(:graphics_element,
|
||||
graphic_type: "Logo",text: "Some Text",
|
||||
timecode_in: "00:00:05:00", timecode_out: "00:00:10:00")
|
||||
end
|
||||
|
||||
subject { described_class.new(workbook, [graphics_element], video) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns the title of the sheet" do
|
||||
expect(subject.title).to eq "Internal Program GFX Log"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from the data" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_row)
|
||||
allow(BigMediaTime).to receive(:time_zone_now).and_return(Date.new(2019,10,4))
|
||||
|
||||
subject.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with(["", "Episode Title:", "My Video", "", "", "", "",])
|
||||
expect(sheet).to have_received(:add_row).with(["", "Episode Number:", "10", "", "", "", "",])
|
||||
expect(sheet).to have_received(:add_row).with(["", "Date:", "10/04/19", "", "", "", "",])
|
||||
expect(sheet).to have_received(:add_row).with(["Logo", "Some Text", "00:00:05:00", "00:00:10:00", "", "", "",])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets sheet column widths and merges cells" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths)
|
||||
expect(sheet).to have_received(:merge_cells).at_least(1).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_style)
|
||||
|
||||
subject.style(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_style).at_least(1).times
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module IssuesAndConcernsReports
|
||||
RSpec.describe IssuesAndConcernsReport do
|
||||
let(:video) { create(:video) }
|
||||
|
||||
subject { described_class.new(video) }
|
||||
|
||||
describe "#to_xls" do
|
||||
it "returns xls file" do
|
||||
expect(subject.to_xls).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "#filename" do
|
||||
it "return 'video_file-mp4_issues-and-concerns.xlsx'" do
|
||||
expect(subject.filename).to eq "video_file-mp4_issues-and-concerns.xlsx"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,116 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module IssuesAndConcernsReports
|
||||
RSpec.describe IssuesAndConcernsWorksheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
it_behaves_like "a worksheet" do
|
||||
subject { described_class.new(workbook) }
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Issues and Concerns Report'" do
|
||||
expect(described_class.new(workbook).title).to eq "Issues and Concerns Report"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from acquired media release" do
|
||||
presenter = instance_double(
|
||||
IssuesAndConcernsReportPresenter,
|
||||
project_name: "Broadcast across the nation",
|
||||
video_name: "The News",
|
||||
date_of_report: "Today",
|
||||
unreleased_appearances: [
|
||||
instance_double(UnreleasedAppearance,
|
||||
timecode_in: "timecode_in",
|
||||
timecode_out: "timecode_out",
|
||||
channel: "channel",
|
||||
source_file_name: "source_file_name",
|
||||
clip_name: "clip_name",
|
||||
note_text: "Great notes",
|
||||
)],
|
||||
)
|
||||
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
expect(sheet).to receive(:add_row).with(["ISSUES AND CONCERNS REPORT"])
|
||||
expect(sheet).to receive(:add_row).with(["Project Name", "Broadcast across the nation"])
|
||||
expect(sheet).to receive(:add_row).with(["Video Name", "The News"])
|
||||
expect(sheet).to receive(:add_row).with(["Date of Report", "Today"])
|
||||
expect(sheet).to receive(:add_row).with([])
|
||||
expect(sheet).to receive(:add_row).with(["Track", "TC In", "TC Out", "Clip Name", "Source File Name", "Notes"])
|
||||
expect(sheet).to receive(:add_row).with(["channel", "timecode_in", "timecode_out", "clip_name", "source_file_name", "Great notes"])
|
||||
|
||||
described_class.new(workbook, presenter).fill_content(sheet)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
|
||||
|
||||
before :each do
|
||||
allow(sheet).to receive(:column_widths)
|
||||
end
|
||||
|
||||
it "sets sheet column widths to 15, 15, 15, 15, 15, 50" do
|
||||
expect(sheet).to receive(:column_widths).with(15, 15, 15, 15, 15, 50)
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
expect(sheet).to receive(:add_style).with("A1", { b: true }, { sz: 14 })
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"A2:A4",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :wrap_text => true },
|
||||
sz: 12,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"B2:B4",
|
||||
{
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :wrap_text => true, :horizontal => :left },
|
||||
sz: 10,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"A6:F6",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
|
||||
sz: 8,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).at_least(1).with(
|
||||
"A7:F8",
|
||||
{
|
||||
border: { style: :thick, color: "000000" },
|
||||
alignment: { wrap_text: true },
|
||||
sz: 10
|
||||
}
|
||||
)
|
||||
|
||||
presenter = instance_double(
|
||||
IssuesAndConcernsReportPresenter,
|
||||
unreleased_appearances: [
|
||||
instance_double(UnreleasedAppearance, timecode_in: "yesterday", notes: "Great notes"),
|
||||
instance_double(UnreleasedAppearance, timecode_in: "yesterday", notes: "Great notes"),
|
||||
],
|
||||
)
|
||||
described_class.new(workbook, presenter).style(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
RSpec.describe DiscoveryProductionElementsLog do
|
||||
let(:video) { create(:video) }
|
||||
|
||||
describe "#to_xls" do
|
||||
it "generates an excel report" do
|
||||
expect(described_class.new(video).to_xls).not_to be_nil
|
||||
end
|
||||
|
||||
it "builds the necessary worksheets" do
|
||||
allow(DiscoveryProductionElementsLogs::MediaRightsCertificationSheet).to receive(:build)
|
||||
allow(DiscoveryProductionElementsLogs::AcquiredFootageAndStillsSheet).to receive(:build)
|
||||
allow(DiscoveryProductionElementsLogs::MusicSheet).to receive(:build)
|
||||
allow(DiscoveryProductionElementsLogs::TalentSheet).to receive(:build)
|
||||
allow(DiscoveryProductionElementsLogs::AppearanceSheet).to receive(:build)
|
||||
allow(DiscoveryProductionElementsLogs::LocationSheet).to receive(:build)
|
||||
allow(DiscoveryProductionElementsLogs::NameProductLogoSheet).to receive(:build)
|
||||
allow(DiscoveryProductionElementsLogs::ProductIntegrationSheet).to receive(:build)
|
||||
|
||||
described_class.new(video).to_xls
|
||||
|
||||
expect(DiscoveryProductionElementsLogs::MediaRightsCertificationSheet).to have_received(:build)
|
||||
expect(DiscoveryProductionElementsLogs::AcquiredFootageAndStillsSheet).to have_received(:build)
|
||||
expect(DiscoveryProductionElementsLogs::MusicSheet).to have_received(:build)
|
||||
expect(DiscoveryProductionElementsLogs::TalentSheet).to have_received(:build)
|
||||
expect(DiscoveryProductionElementsLogs::AppearanceSheet).to have_received(:build)
|
||||
expect(DiscoveryProductionElementsLogs::LocationSheet).to have_received(:build)
|
||||
expect(DiscoveryProductionElementsLogs::NameProductLogoSheet).to have_received(:build)
|
||||
expect(DiscoveryProductionElementsLogs::ProductIntegrationSheet).to have_received(:build)
|
||||
end
|
||||
|
||||
it "sorts the worksheet data by timecode in" do
|
||||
confirmations = double(:video_release_confirmations)
|
||||
allow(video).to receive(:video_release_confirmations).and_return(confirmations)
|
||||
allow(confirmations).to receive(:where).and_return(confirmations)
|
||||
allow(confirmations).to receive(:order).and_return([])
|
||||
|
||||
described_class.new(video).to_xls
|
||||
|
||||
expect(video).to have_received(:video_release_confirmations).exactly(6).times
|
||||
expect(confirmations).to have_received(:where).exactly(6).times
|
||||
expect(confirmations).to have_received(:order).with(timecode_in: :asc).exactly(6).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#filename" do
|
||||
it "returns video file filename concatenated with production-elements-log and given format" do
|
||||
expect(described_class.new(video).filename("csv")).to eq "video_file-mp4_production-elements-log.csv"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,146 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module DiscoveryProductionElementsLogs
|
||||
RSpec.describe AcquiredFootageAndStillsSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
it_behaves_like "a worksheet" do
|
||||
subject { described_class.new(workbook) }
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Acquired Footage & Stills'" do
|
||||
expect(described_class.new(workbook).title).to eq "Acquired Footage & Stills"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from acquired media release" do
|
||||
instructions = <<~INSTRUCTIONS
|
||||
All licenses must conform to the DCI contractual requirements and must be fully executed.
|
||||
|
||||
Releases, licenses and agreements should only be logged once, based on the order of their appearance in the program.
|
||||
|
||||
If an image does not appear in the final Program, log that release after those in the final Program; indicate on the Log sheet “NOT IN FINAL PROGRAM” and list the camera tape only.
|
||||
|
||||
Refer to the source of all third party footage in the exact form as it appears on the release.
|
||||
|
||||
Please note that if it is not possible to deliver an English language agreement, an English language translation must accompany any agreement delivered in a foreign language (if applicable).
|
||||
INSTRUCTIONS
|
||||
user = create(:user)
|
||||
project = create(:project, account:user.primary_account)
|
||||
video = create(:video,
|
||||
project: project,
|
||||
number: "45",
|
||||
name: "Amazing Race",
|
||||
)
|
||||
acquired_media_release = create(:acquired_media_release,
|
||||
project: project,
|
||||
applicable_medium: ApplicableMedium.last,
|
||||
territory: Territory.last,
|
||||
term: Term.last,
|
||||
restriction: Restriction.last,
|
||||
name: "Licensor",
|
||||
person_phone: "1-800-978-2343",
|
||||
)
|
||||
confirmation = create(:video_release_confirmation,
|
||||
video: video,
|
||||
releasable: acquired_media_release,
|
||||
source_file_name: "source_file_name",
|
||||
clip_name: "clippy",
|
||||
timecode_in: "timecode_in",
|
||||
timecode_out: "timecode_out",
|
||||
duration: "duration",
|
||||
description: "description",
|
||||
)
|
||||
wrapped_confirmation = ReleasableDataAdapter.new(confirmation)
|
||||
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
expect(sheet).to receive(:add_row).with(["ACQUIRED FOOTAGE/STILLS/ PUBLIC DOMAIN LOG (for all episodes/programs)"])
|
||||
expect(sheet).to receive(:add_row).with([instructions])
|
||||
expect(sheet).to receive(:add_row).with(no_args)
|
||||
expect(sheet).to receive(:add_row).with(["EPISODE NUMBER", "EPISODE TITLE", "CLIP #", "PROGRAM MASTER TC", "", "TOTAL TIME", "BRIEF VIDEO DESCRIPTION", "LICENSOR\n(incl phone number)", "EXPLOITABLE RIGHTS", "", "", "DCL Rights Waiver Uploaded?"])
|
||||
expect(sheet).to receive(:add_row).with(["", "", "", "IN", "OUT", "", "", "", "MEDIA", "TERRITORY", "TERM", ""])
|
||||
expect(sheet).to receive(:add_row).with(["45", "Amazing Race", "source_file_name - clippy", "timecode_in", "timecode_out", "duration", "description", "Licensor\n1-800-978-2343", "All", "Worldwide", "In perpetuity", "None"])
|
||||
|
||||
described_class.new(workbook, [wrapped_confirmation]).fill_content(sheet)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
|
||||
|
||||
before :each do
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
end
|
||||
|
||||
it "sets sheet column widths to 10, 20, 25, 15, 15, 15, 20, 15, 15, 15, 15, 10" do
|
||||
expect(sheet).to receive(:column_widths).with(10, 20, 25, 15, 15, 15, 20, 15, 15, 15, 15, 10)
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
|
||||
it "merges columns A1:M1 A2:M2 A4:A5 B4:B5 C4:C5 D4:E4 F4:F5 G4:G5 H4:H5 I4:K4 L4:L5" do
|
||||
%w(A1:M1 A2:M2 A4:A5 B4:B5 C4:C5 D4:E4 F4:F5 G4:G5 H4:H5 I4:K4 L4:L5).each do |cell|
|
||||
expect(sheet).to receive(:merge_cells).with(cell)
|
||||
end
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
expect(sheet).to receive(:add_style).with("A1", { b: true }, { sz: 14 })
|
||||
expect(sheet).to receive(:add_style).with("A2", { sz: 10 })
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"A4:L4",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
|
||||
sz: 8,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"B5:L5",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
|
||||
sz: 8,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"A4",
|
||||
{
|
||||
alignment: { :wrap_text => true },
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"L4",
|
||||
{
|
||||
alignment: { :wrap_text => true },
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).at_least(1).with("A6:L7",
|
||||
{
|
||||
border: { style: :thick, color: "000000" },
|
||||
alignment: { wrap_text: true },
|
||||
sz: 10
|
||||
}
|
||||
)
|
||||
|
||||
described_class.new(workbook, ["data1", "data2"]).style(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,74 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module DiscoveryProductionElementsLogs
|
||||
RSpec.describe AppearanceSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
it_behaves_like "a worksheet" do
|
||||
subject { described_class.new(workbook) }
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Appearance'" do
|
||||
expect(described_class.new(workbook).title).to eq "Appearance"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from the data" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
releasable_datum = ReleasableDataAdapter.new(
|
||||
build(:video_release_confirmation,
|
||||
timecode_in: "00:00:05:00",
|
||||
time_elapsed: 1,
|
||||
source_file_name: "source",
|
||||
clip_name: "clip",
|
||||
description: "old, male, brunette",
|
||||
video: build(:video, name: "My Video", number: 1),
|
||||
releasable: build(:appearance_release, person_first_name: "John", person_last_name: "Doe")
|
||||
)
|
||||
)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
release_log = described_class.new(workbook, [releasable_datum])
|
||||
release_log.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"1",
|
||||
"My Video",
|
||||
"00:00:05:00",
|
||||
"source - clip",
|
||||
"John Doe",
|
||||
"old, male, brunette",
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
|
||||
|
||||
before :each do
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
end
|
||||
|
||||
it "sets sheet column widths to 20, 25, 20, 20, 25, 30" do
|
||||
expect(sheet).to receive(:column_widths).with(20, 25, 20, 20, 25, 30)
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
|
||||
it "merges columns A2:F2" do
|
||||
%w(A2:F2).each do |cell|
|
||||
expect(sheet).to receive(:merge_cells).with(cell)
|
||||
end
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,65 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module DiscoveryProductionElementsLogs
|
||||
RSpec.describe LocationSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
it_behaves_like "a worksheet" do
|
||||
subject { described_class.new(workbook) }
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Location'" do
|
||||
expect(described_class.new(workbook).title).to eq "Location"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from the data" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
releasable_datum = ReleasableDataAdapter.new(
|
||||
build(:video_release_confirmation,
|
||||
timecode_in: "00:00:05:00",
|
||||
time_elapsed: 1,
|
||||
source_file_name: "source",
|
||||
clip_name: "clip",
|
||||
description: "restaurant",
|
||||
video: build(:video, name: "My Video", number: 1),
|
||||
releasable: build(:location_release, name: "Frank's Taco Shack")
|
||||
)
|
||||
)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
release_log = described_class.new(workbook, [releasable_datum])
|
||||
release_log.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"1",
|
||||
"My Video",
|
||||
"00:00:05:00",
|
||||
"source - clip",
|
||||
"Frank's Taco Shack restaurant",
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
|
||||
|
||||
before :each do
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
end
|
||||
|
||||
it "sets sheet column widths to 20, 20, 15, 20, 40" do
|
||||
expect(sheet).to receive(:column_widths).with(20, 20, 15, 20, 40)
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module DiscoveryProductionElementsLogs
|
||||
RSpec.describe MediaRightsCertificationSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
it_behaves_like "a worksheet" do
|
||||
subject { described_class.new(workbook) }
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Media Rights Certification'" do
|
||||
expect(described_class.new(workbook).title).to eq "Media Rights Certification"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
|
||||
|
||||
before :each do
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
end
|
||||
|
||||
it "sets sheet column widths to 10, 20, 10, 10, 10, 10, 10, 10, 10, 10" do
|
||||
expect(sheet).to receive(:column_widths).with(10, 20, 10, 10, 10, 10, 10, 10, 10, 10)
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
|
||||
it "merges columns A1:J1 A2:J2 A3:J3 B4:J4 B5:J5 B6:J6 A8:J8 B9:J9 B10:J10 B11:J11 B12:J12 B13:J13 A14:J14 A15:J15" do
|
||||
%w(A1:J1 A2:J2 A3:J3 B4:J4 B5:J5 B6:J6 A8:J8 B9:J9 B10:J10 B11:J11 B12:J12 B13:J13 A14:J14 A15:J15).each do |cell|
|
||||
expect(sheet).to receive(:merge_cells).with(cell)
|
||||
end
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,98 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module DiscoveryProductionElementsLogs
|
||||
RSpec.describe MusicSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
it_behaves_like "a worksheet" do
|
||||
subject { described_class.new(workbook) }
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Music'" do
|
||||
expect(described_class.new(workbook).title).to eq "Music"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from music release" do
|
||||
user = create(:user)
|
||||
project = create(:project, account:user.primary_account)
|
||||
video = create(:video,
|
||||
project: project,
|
||||
number: "45",
|
||||
name: "Amazing Race",
|
||||
)
|
||||
confirmation = create(:audio_confirmation,
|
||||
video: video,
|
||||
source_file_name: "source_file_name",
|
||||
composer_info: "composer1, affiliation, 50%|composer2, affiliation, 50%",
|
||||
publisher_info: "publisher1, affiliation, 50%|publisher2, affiliation, 50%",
|
||||
confirmation_type: "original_music"
|
||||
)
|
||||
wrapped_confirmation = ReleasableDataAdapter.new(confirmation)
|
||||
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
expect(sheet).to receive(:add_row).with(["MUSIC LOG (for all episodes/programs) for commissioned work-for-hire music only"])
|
||||
expect(sheet).to receive(:add_row).with(["Not applicable if program contains 100% library"])
|
||||
expect(sheet).to receive(:add_row).with(["Episode Title(s) or list \"All\"", "TRACK TITLE", "COMPOSER", "PUBLISHER"])
|
||||
expect(sheet).to receive(:add_row).with(["Amazing Race", "source_file_name", "composer1, affiliation, 50%\ncomposer2, affiliation, 50%", "publisher1, affiliation, 50%\npublisher2, affiliation, 50%"])
|
||||
|
||||
described_class.new(workbook, [wrapped_confirmation]).fill_content(sheet)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
|
||||
|
||||
before :each do
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
end
|
||||
|
||||
it "sets sheet column widths to 20, 20, 30, 60" do
|
||||
expect(sheet).to receive(:column_widths).with(20, 20, 30, 60)
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
expect(sheet).to receive(:add_style).with("A1", { b: true }, { sz: 14 })
|
||||
expect(sheet).to receive(:add_style).with("A2", { sz: 14 })
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"A3:D3",
|
||||
{
|
||||
bg_color: "97CBFC",
|
||||
b: true,
|
||||
border: { :style => :thick, :color => "000000" },
|
||||
alignment: { :horizontal => :center, :vertical => :center, :wrap_text => true },
|
||||
sz: 8,
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).with(
|
||||
"A3",
|
||||
{
|
||||
alignment: { :wrap_text => true },
|
||||
}
|
||||
)
|
||||
expect(sheet).to receive(:add_style).at_least(1).with(
|
||||
"A4:D5",
|
||||
{
|
||||
border: { style: :thick, color: "000000" },
|
||||
alignment: { wrap_text: true },
|
||||
sz: 10
|
||||
}
|
||||
)
|
||||
|
||||
described_class.new(workbook, ["data1", "data2"]).style(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,65 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module DiscoveryProductionElementsLogs
|
||||
RSpec.describe NameProductLogoSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
it_behaves_like "a worksheet" do
|
||||
subject { described_class.new(workbook) }
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Name Product Logo'" do
|
||||
expect(described_class.new(workbook).title).to eq "Name Product Logo"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from the data" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
releasable_datum = ReleasableDataAdapter.new(
|
||||
build(:video_release_confirmation,
|
||||
timecode_in: "00:00:05:00",
|
||||
time_elapsed: 1,
|
||||
source_file_name: "source",
|
||||
clip_name: "clip",
|
||||
description: "brand, can, soda",
|
||||
video: build(:video, name: "My Video", number: 1),
|
||||
releasable: build(:material_release, name: "Coca Cola")
|
||||
)
|
||||
)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
release_log = described_class.new(workbook, [releasable_datum])
|
||||
release_log.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"1",
|
||||
"My Video",
|
||||
"00:00:05:00",
|
||||
"source - clip",
|
||||
"Coca Cola",
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
|
||||
|
||||
before :each do
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
end
|
||||
|
||||
it "sets sheet column widths to 15, 25, 15, 20, 40" do
|
||||
expect(sheet).to receive(:column_widths).with(15, 25, 15, 20, 40)
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module DiscoveryProductionElementsLogs
|
||||
RSpec.describe ProductIntegrationSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
it_behaves_like "a worksheet" do
|
||||
subject { described_class.new(workbook) }
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Product Integration'" do
|
||||
expect(described_class.new(workbook).title).to eq "Product Integration"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
|
||||
|
||||
before :each do
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
end
|
||||
|
||||
it "sets sheet column widths to 15, 15, 15, 15, 15, 15, 15, 15, 15, 15" do
|
||||
expect(sheet).to receive(:column_widths).with(15, 15, 15, 15, 15, 15, 15, 15, 15, 15)
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
|
||||
it "merges columns A4:A5 B4:B5 C4:C5 D4:D5 E4:E5 F4:F5 G4:G5 H4:H5 I4:J4" do
|
||||
%w(A4:A5 B4:B5 C4:C5 D4:D5 E4:E5 F4:F5 G4:G5 H4:H5 I4:J4).each do |cell|
|
||||
expect(sheet).to receive(:merge_cells).with(cell)
|
||||
end
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module DiscoveryProductionElementsLogs
|
||||
RSpec.describe TalentSheet do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
it_behaves_like "a worksheet" do
|
||||
subject { described_class.new(workbook) }
|
||||
end
|
||||
|
||||
describe "#title" do
|
||||
it "returns 'Talent'" do
|
||||
expect(described_class.new(workbook).title).to eq "Talent"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from the data" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
releasable_datum = ReleasableDataAdapter.new(
|
||||
build(:video_release_confirmation,
|
||||
video: build(:video, name: "My Video", number: 1),
|
||||
releasable: build(:talent_release, person_first_name: "John", person_last_name: "Doe")
|
||||
)
|
||||
)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
release_log = described_class.new(workbook, [releasable_datum])
|
||||
release_log.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
"1",
|
||||
"My Video",
|
||||
"",
|
||||
"John Doe",
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
let(:sheet) { instance_double(Axlsx::Worksheet, :sheet) }
|
||||
|
||||
before :each do
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
end
|
||||
|
||||
it "sets sheet column widths to 20, 20, 30, 60" do
|
||||
expect(sheet).to receive(:column_widths).with(20, 20, 30, 60)
|
||||
|
||||
described_class.new(workbook).format(sheet)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,53 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
RSpec.describe NatGeoLegalBinderLog, type: :model do
|
||||
let(:video) { create(:video) }
|
||||
|
||||
subject { described_class.new(video) }
|
||||
|
||||
describe "#to_xls" do
|
||||
it "generates an excel report" do
|
||||
expect(subject.to_xls).not_to be_nil
|
||||
end
|
||||
|
||||
it "builds the necessary worksheets" do
|
||||
allow(NatGeoLegalBinderLogs::LegalBinderChecklistSheet).to receive(:build)
|
||||
allow(NatGeoLegalBinderLogs::AppearanceReleaseLogSheet).to receive(:build)
|
||||
allow(NatGeoLegalBinderLogs::LocationReleaseLogSheet).to receive(:build)
|
||||
allow(NatGeoLegalBinderLogs::AcquiredFootageLogSheet).to receive(:build)
|
||||
allow(NatGeoLegalBinderLogs::ThirdPartyContractLogSheet).to receive(:build)
|
||||
allow(NatGeoLegalBinderLogs::ProductionPersonnelLogSheet).to receive(:build)
|
||||
|
||||
described_class.new(video).to_xls
|
||||
|
||||
expect(NatGeoLegalBinderLogs::LegalBinderChecklistSheet).to have_received(:build)
|
||||
expect(NatGeoLegalBinderLogs::LocationReleaseLogSheet).to have_received(:build)
|
||||
expect(NatGeoLegalBinderLogs::AcquiredFootageLogSheet).to have_received(:build)
|
||||
expect(NatGeoLegalBinderLogs::ThirdPartyContractLogSheet).to have_received(:build)
|
||||
expect(NatGeoLegalBinderLogs::ProductionPersonnelLogSheet).to have_received(:build)
|
||||
end
|
||||
|
||||
it "sorts the worksheet data by timecode in" do
|
||||
confirmations = double(:video_release_confirmations)
|
||||
allow(video).to receive(:video_release_confirmations).and_return(confirmations)
|
||||
allow(confirmations).to receive(:where).and_return(confirmations)
|
||||
allow(confirmations).to receive(:order).and_return([])
|
||||
|
||||
described_class.new(video).to_xls
|
||||
|
||||
expect(video).to have_received(:video_release_confirmations).exactly(3).times
|
||||
expect(confirmations).to have_received(:where).exactly(3).times
|
||||
expect(confirmations).to have_received(:order).with(timecode_in: :asc).exactly(3).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#filename" do
|
||||
it "includes video file filename, report title, and format" do
|
||||
expect(subject.filename).to eq "video_file-mp4_legal-binder-log.xlsx"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,88 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module NatGeoLegalBinderLogs
|
||||
RSpec.describe AcquiredFootageLogSheet, type: :model do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
subject { described_class.new(workbook, []) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns the title of the sheet" do
|
||||
expect(subject.title).to eq "Acquired Footage-Stills Log"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from the data" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
releasable_datum = ReleasableDataAdapter.new(
|
||||
build(:video_release_confirmation,
|
||||
source_file_name: "source",
|
||||
clip_name: "clippy",
|
||||
timecode_in: "00:00:05:00",
|
||||
timecode_out: "00:00:10:00",
|
||||
duration: "00:00:15",
|
||||
description: "Media description",
|
||||
releasable: build(:acquired_media_release,
|
||||
applicable_medium: ApplicableMedium.last,
|
||||
territory: Territory.last,
|
||||
term: Term.last,
|
||||
restriction: Restriction.last,
|
||||
name: "Licensor",
|
||||
person_address_street1: "123 Main Street",
|
||||
person_address_city: "New York",
|
||||
person_address_state: "NY",
|
||||
person_address_zip: "10000",
|
||||
)
|
||||
)
|
||||
)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
release_log = described_class.new(workbook, [releasable_datum])
|
||||
release_log.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
1,
|
||||
"Media description",
|
||||
"00:00:05:00",
|
||||
"00:00:10:00",
|
||||
"Licensor\n123 Main Street, New York, NY 10000",
|
||||
"All",
|
||||
"Worldwide",
|
||||
"In perpetuity",
|
||||
"None",
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets column widths and merges cells" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths)
|
||||
expect(sheet).to have_received(:merge_cells).at_least(1).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_style)
|
||||
|
||||
subject.style(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_style).at_least(1).times
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,75 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module NatGeoLegalBinderLogs
|
||||
RSpec.describe AppearanceReleaseLogSheet, type: :model do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
subject { described_class.new(workbook, []) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns the title of the sheet" do
|
||||
expect(subject.title).to eq "Appearance Release Log"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from the data" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
releasable_datum = ReleasableDataAdapter.new(
|
||||
build(:video_release_confirmation,
|
||||
timecode_in: "00:00:05:00",
|
||||
releasable: build(:appearance_release,
|
||||
applicable_medium: ApplicableMedium.last,
|
||||
territory: Territory.last,
|
||||
term: Term.last,
|
||||
restriction: Restriction.last,
|
||||
person_first_name: "John",
|
||||
person_last_name: "Doe",
|
||||
person_address: "123 Main Street, New York, NY 10000")
|
||||
)
|
||||
)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
release_log = described_class.new(workbook, [releasable_datum])
|
||||
release_log.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
1,
|
||||
"00:00:05:00",
|
||||
"John Doe\n123 Main Street, New York, NY 10000",
|
||||
"All", "Worldwide", "In perpetuity", "", "None",
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets column widths and merges cells" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths)
|
||||
expect(sheet).to have_received(:merge_cells).at_least(1).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_style)
|
||||
|
||||
subject.style(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_style).at_least(1).times
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module NatGeoLegalBinderLogs
|
||||
RSpec.describe LegalBinderChecklistSheet, type: :model do
|
||||
let(:video) { build(:video, number: 1, name: "My Episode") }
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
subject { described_class.new(workbook, [], video) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns the title of the sheet" do
|
||||
expect(subject.title).to eq "Legal Binder Checklist"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from the video" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
subject.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with(["SERIES TITLE:", ""])
|
||||
expect(sheet).to have_received(:add_row).with(["EPISODE NUMBER:","1"])
|
||||
expect(sheet).to have_received(:add_row).with(["EPISODE TITLE:", "My Episode"])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets column widths and merges cells" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths)
|
||||
expect(sheet).to have_received(:merge_cells).at_least(1).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_style)
|
||||
|
||||
subject.style(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_style).at_least(1).times
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,78 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module NatGeoLegalBinderLogs
|
||||
RSpec.describe LocationReleaseLogSheet, type: :model do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
subject { described_class.new(workbook, []) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns the title of the sheet" do
|
||||
expect(subject.title).to eq "Location Release Log"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content from the data" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
releasable_datum = ReleasableDataAdapter.new(
|
||||
build(:video_release_confirmation,
|
||||
timecode_in: "00:00:05:00",
|
||||
releasable: build(:location_release,
|
||||
applicable_medium: ApplicableMedium.last,
|
||||
territory: Territory.last,
|
||||
term: Term.last,
|
||||
restriction: Restriction.last,
|
||||
name: "My Location",
|
||||
address_street1: "123 Main Street",
|
||||
address_city: "New York",
|
||||
address_state: "NY",
|
||||
address_zip: "10000")
|
||||
)
|
||||
)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
release_log = described_class.new(workbook, [releasable_datum])
|
||||
release_log.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).with([
|
||||
1,
|
||||
"00:00:05:00",
|
||||
"My Location\n123 Main Street, New York, NY 10000",
|
||||
"",
|
||||
"All", "Worldwide", "In perpetuity", "", "None",
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets column widths and merges cells" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths)
|
||||
expect(sheet).to have_received(:merge_cells).at_least(1).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_style)
|
||||
|
||||
subject.style(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_style).at_least(1).times
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module NatGeoLegalBinderLogs
|
||||
RSpec.describe ProductionPersonnelLogSheet, type: :model do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
subject { described_class.new(workbook, []) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns the title of the sheet" do
|
||||
expect(subject.title).to eq "Production Personnel Log"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content for the table" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
subject.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).exactly(12).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets column widths and merges cells" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_style)
|
||||
|
||||
subject.style(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_style).at_least(1).times
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
module NatGeoLegalBinderLogs
|
||||
RSpec.describe ThirdPartyContractLogSheet, type: :model do
|
||||
let(:workbook) { instance_double(Axlsx::Workbook, :workbook) }
|
||||
|
||||
subject { described_class.new(workbook, []) }
|
||||
|
||||
it_behaves_like "a worksheet"
|
||||
|
||||
describe "#title" do
|
||||
it "returns the title of the sheet" do
|
||||
expect(subject.title).to eq "Third Party Contract Log"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fill_content" do
|
||||
it "adds content for the table" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_row)
|
||||
|
||||
subject.fill_content(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_row).exactly(13).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#format" do
|
||||
it "sets column widths and merges cells" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:column_widths)
|
||||
allow(sheet).to receive(:merge_cells)
|
||||
|
||||
subject.format(sheet)
|
||||
|
||||
expect(sheet).to have_received(:column_widths)
|
||||
expect(sheet).to have_received(:merge_cells).at_least(1).times
|
||||
end
|
||||
end
|
||||
|
||||
describe "#style" do
|
||||
it "sets sheet style" do
|
||||
sheet = instance_double(Axlsx::Worksheet, :sheet)
|
||||
allow(sheet).to receive(:add_style)
|
||||
|
||||
subject.style(sheet)
|
||||
|
||||
expect(sheet).to have_received(:add_style).at_least(1).times
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,134 @@
|
||||
require "rails_helper"
|
||||
|
||||
module ExcelReports
|
||||
module VideoReports
|
||||
RSpec.describe ReleasableDataAdapter do
|
||||
let(:user) { create(:user) }
|
||||
let(:project) { create(:project, account:user.primary_account, description: "This is the video project description.") }
|
||||
let(:video) { create(:video, project: project, number: "45", name: "Amazing Race") }
|
||||
let(:acquired_media_release) { create(:acquired_media_release, project: project, name: "releasable name", person_address_street1: "contact_address") }
|
||||
let(:confirmation) do
|
||||
create(:video_release_confirmation,
|
||||
video: video,
|
||||
releasable: acquired_media_release,
|
||||
clip_name: "clippy",
|
||||
timecode_in: "timecode_in",
|
||||
timecode_out: "timecode_out",
|
||||
duration: "duration",
|
||||
description: "description",
|
||||
source_file_name: "cat.mov"
|
||||
)
|
||||
end
|
||||
|
||||
subject { described_class.new(confirmation) }
|
||||
|
||||
describe "#description" do
|
||||
context "when confirmation contains description" do
|
||||
it "returns description from confirmation" do
|
||||
expect(subject.description).to eq "description"
|
||||
end
|
||||
end
|
||||
|
||||
context "when confirmation does NOT contain description" do
|
||||
it "returns project description" do
|
||||
confirmation.description = nil
|
||||
|
||||
expect(subject.description).to eq "This is the video project description."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#episode_number" do
|
||||
it "returns video number" do
|
||||
expect(subject.episode_number).to eq "45"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#episode_title" do
|
||||
it "returns video name" do
|
||||
expect(subject.episode_title).to eq "Amazing Race"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#name" do
|
||||
it "returns releasable name" do
|
||||
expect(subject.name).to eq "releasable name"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#source_file_name" do
|
||||
it "returns source_file_name from confirmation" do
|
||||
expect(subject.source_file_name).to eq "cat.mov"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#clip_name" do
|
||||
it "returns clip_name from confirmation" do
|
||||
expect(subject.clip_name).to eq "clippy"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#source_file_and_clip_names" do
|
||||
context "when source_file_name and clip_name present" do
|
||||
it "returns source_file_name and clip_name from confirmation joined by -" do
|
||||
expect(subject.source_file_and_clip_names).to eq "cat.mov - clippy"
|
||||
end
|
||||
end
|
||||
|
||||
context "when only source_file_name present" do
|
||||
it "returns source_file_name from confirmation" do
|
||||
confirmation.source_file_name = "cat.mov"
|
||||
confirmation.clip_name = nil
|
||||
expect(subject.source_file_and_clip_names).to eq "cat.mov"
|
||||
end
|
||||
end
|
||||
|
||||
context "when only clip_name present" do
|
||||
it "returns clip_name from confirmation" do
|
||||
confirmation.source_file_name = nil
|
||||
confirmation.clip_name = "clippy"
|
||||
expect(subject.source_file_and_clip_names).to eq "clippy"
|
||||
end
|
||||
end
|
||||
|
||||
context "when source_file_name and clip_name present" do
|
||||
it "returns empty string" do
|
||||
confirmation.source_file_name = nil
|
||||
confirmation.clip_name = ""
|
||||
expect(subject.source_file_and_clip_names).to eq ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#timecode_in" do
|
||||
it "returns timecode_in from confirmation" do
|
||||
expect(subject.timecode_in).to eq "timecode_in"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#timecode_out" do
|
||||
it "returns timecode_out from confirmation" do
|
||||
expect(subject.timecode_out).to eq "timecode_out"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#duration" do
|
||||
it "returns duration from confirmation" do
|
||||
expect(subject.duration).to eq "duration"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#confirmation" do
|
||||
it "returns given confirmation" do
|
||||
expect(subject.confirmation).to eq confirmation
|
||||
end
|
||||
end
|
||||
|
||||
describe "#contact_address" do
|
||||
it "returns address from contact info" do
|
||||
expect(subject.contact_address).to eq("contact_address")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
32
spec/models/file_info_spec.rb
Normal file
32
spec/models/file_info_spec.rb
Normal file
@@ -0,0 +1,32 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe FileInfo, type: :model do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:releasable) }
|
||||
end
|
||||
|
||||
describe ".audio" do
|
||||
it "returns only audio files" do
|
||||
audio_content_types = %w(audio/mpeg audio/x-aiff audio/aiff audio/wav audio/vnd.wave audio/wav audio/wave audio/x-wav)
|
||||
|
||||
audio_files = audio_content_types.map do |content_type|
|
||||
create(:file_info, content_type: content_type)
|
||||
end
|
||||
|
||||
non_audio_files = [
|
||||
create(:file_info, content_type: "video/mp4"),
|
||||
create(:file_info, content_type: ""),
|
||||
]
|
||||
|
||||
results = FileInfo.audio
|
||||
|
||||
audio_files.each do |audio_file|
|
||||
expect(results).to include(audio_file)
|
||||
end
|
||||
|
||||
non_audio_files.each do |non_audio_file|
|
||||
expect(results).not_to include(non_audio_file)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
54
spec/models/files_for_request_spec.rb
Normal file
54
spec/models/files_for_request_spec.rb
Normal file
@@ -0,0 +1,54 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe FilesForRequest do
|
||||
let(:video) do
|
||||
create(:video, analysis_uid: "analysis_uid") do |video|
|
||||
video.file.key = "awesome"
|
||||
video.edl_file.key = "sauce"
|
||||
end
|
||||
end
|
||||
|
||||
subject { described_class.new(video) }
|
||||
|
||||
describe "#start_timecode_offset" do
|
||||
it "returns nil" do
|
||||
expect(subject.start_timecode_offset).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "#file_object_name" do
|
||||
it "returns file key" do
|
||||
expect(subject.file_object_name).to eq "awesome"
|
||||
end
|
||||
|
||||
it "returns nil when no video file attached" do
|
||||
video.file.purge
|
||||
expect(subject.file_object_name).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "#edl_file_object_name" do
|
||||
it "returns edl file key" do
|
||||
expect(subject.edl_file_object_name).to eq "sauce"
|
||||
end
|
||||
|
||||
it "returns nil when no video file attached" do
|
||||
video.edl_file.purge
|
||||
expect(subject.edl_file_object_name).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "#aws_bucket_name" do
|
||||
it "returns AWS bucket name" do
|
||||
allow(ENV).to receive(:[])
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("bucket")
|
||||
expect(subject.aws_bucket_name).to eq "bucket"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#job_id" do
|
||||
it "returns the analysis uid of the video" do
|
||||
expect(subject.job_id).to eq "analysis_uid"
|
||||
end
|
||||
end
|
||||
end
|
||||
21
spec/models/graphics_element_spec.rb
Normal file
21
spec/models/graphics_element_spec.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe GraphicsElement do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:video) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:graphic_type) }
|
||||
it { is_expected.to validate_presence_of(:text) }
|
||||
it { is_expected.to validate_presence_of(:time_elapsed) }
|
||||
end
|
||||
|
||||
describe "#appears_at" do
|
||||
it "returns formatted timecode" do
|
||||
graphics_element = build(:graphics_element, time_elapsed: "1.039")
|
||||
|
||||
expect(graphics_element.appears_at).to eq "00:00:01:01"
|
||||
end
|
||||
end
|
||||
end
|
||||
54
spec/models/graphics_files_for_request_spec.rb
Normal file
54
spec/models/graphics_files_for_request_spec.rb
Normal file
@@ -0,0 +1,54 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe GraphicsFilesForRequest do
|
||||
let(:video) do
|
||||
create(:video, :with_graphics_only_edl_file, analysis_uid: "analysis_uid") do |video|
|
||||
video.file.key = "awesome"
|
||||
video.graphics_only_edl_file.key = "sauce"
|
||||
end
|
||||
end
|
||||
|
||||
subject { described_class.new(video, "offset") }
|
||||
|
||||
describe "#start_timecode_offset" do
|
||||
it "returns given start_timecode_offset" do
|
||||
expect(subject.start_timecode_offset).to eq "offset"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#file_object_name" do
|
||||
it "returns file key" do
|
||||
expect(subject.file_object_name).to eq "awesome"
|
||||
end
|
||||
|
||||
it "returns nil when no video file attached" do
|
||||
video.file.purge
|
||||
expect(subject.file_object_name).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "#edl_file_object_name" do
|
||||
it "returns graphics edl file key" do
|
||||
expect(subject.edl_file_object_name).to eq "sauce"
|
||||
end
|
||||
|
||||
it "returns nil when no video file attached" do
|
||||
video.graphics_only_edl_file.purge
|
||||
expect(subject.edl_file_object_name).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "#aws_bucket_name" do
|
||||
it "returns AWS bucket name" do
|
||||
allow(ENV).to receive(:[])
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("bucket")
|
||||
expect(subject.aws_bucket_name).to eq "bucket"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#job_id" do
|
||||
it "returns the analysis uid of the video" do
|
||||
expect(subject.job_id).to eq "analysis_uid"
|
||||
end
|
||||
end
|
||||
end
|
||||
114
spec/models/headshot_collection_spec.rb
Normal file
114
spec/models/headshot_collection_spec.rb
Normal file
@@ -0,0 +1,114 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe HeadshotCollection do
|
||||
describe ".for_project" do
|
||||
it "generates a collection for a given project" do
|
||||
project = create(:project,
|
||||
appearance_releases: create_list(:appearance_release, 1),
|
||||
talent_releases: create_list(:talent_release, 1),
|
||||
headshot_collection_uid: "123abc"
|
||||
)
|
||||
|
||||
collection = HeadshotCollection.for_project(project)
|
||||
|
||||
expect(collection).not_to be_nil
|
||||
expect(collection).to be_a(HeadshotCollection)
|
||||
expect(collection.releasables).to include(project.appearance_releases.first)
|
||||
expect(collection.releasables).to include(project.talent_releases.first)
|
||||
expect(collection.collection_uid).to eq(project.headshot_collection_uid)
|
||||
end
|
||||
|
||||
context "when a release has no headshot photo attachment" do
|
||||
it "excludes that release from the headshot collection" do
|
||||
project = create(:project,
|
||||
appearance_releases: build_list(:appearance_release, 1, :without_person_photo),
|
||||
talent_releases: [],
|
||||
)
|
||||
|
||||
collection = HeadshotCollection.for_project(project)
|
||||
expect(collection).to be_a(HeadshotCollection)
|
||||
expect(collection.releasables).not_to include(project.appearance_releases.first)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#as_json" do
|
||||
it "uses the custom hash format" do
|
||||
collection = HeadshotCollection.new "uid", []
|
||||
|
||||
expect(collection.as_json).to eq(collection.to_hash)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_hash" do
|
||||
it "includes the name of the bucket where the headshots are stored" do
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("test-bucket")
|
||||
|
||||
collection = HeadshotCollection.new("uid", [])
|
||||
bucket_name = collection.to_hash[:bucket_name]
|
||||
|
||||
expect(bucket_name).to eq("test-bucket")
|
||||
end
|
||||
|
||||
it "includes the collection UID" do
|
||||
collection = HeadshotCollection.new("uid", [])
|
||||
collection_uid = collection.to_hash[:collection_uid]
|
||||
|
||||
expect(collection_uid).to eq("uid")
|
||||
end
|
||||
|
||||
it "forces the collection UID to be a string" do
|
||||
collection = HeadshotCollection.new(10, [])
|
||||
collection_uid = collection.to_hash[:collection_uid]
|
||||
|
||||
expect(collection_uid).to eq("10")
|
||||
end
|
||||
|
||||
it "includes a mapping of IDs to headshot keys" do
|
||||
releases = build_releases_with_photo_keys(["123", "456"])
|
||||
collection = HeadshotCollection.new("uid", releases)
|
||||
|
||||
mapping = collection.to_hash[:ids_to_images]
|
||||
|
||||
expect(mapping["appearance_release_#{releases.first.id}"]).to include("123")
|
||||
expect(mapping["appearance_release_#{releases.last.id}"]).to include("456")
|
||||
end
|
||||
|
||||
it "differentiates between release types" do
|
||||
releases = [
|
||||
build_release_with_photo_key("123", release_type: :appearance_release),
|
||||
build_release_with_photo_key("456", release_type: :talent_release),
|
||||
]
|
||||
collection = HeadshotCollection.new("uid", releases)
|
||||
|
||||
mapping = collection.to_hash[:ids_to_images]
|
||||
|
||||
expect(mapping["appearance_release_#{releases.first.id}"]).to include("123")
|
||||
expect(mapping["talent_release_#{releases.last.id}"]).to include("456")
|
||||
end
|
||||
|
||||
context "when collection uid is blank" do
|
||||
it "is not included in the hash" do
|
||||
releases = []
|
||||
collection = HeadshotCollection.new(nil, releases)
|
||||
|
||||
hash = collection.to_hash
|
||||
|
||||
expect(hash.keys).not_to include(:collection_uid)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_release_with_photo_key(key, release_type: :appearance_release)
|
||||
build_stubbed(release_type).tap do |release|
|
||||
photo = double(key: key)
|
||||
allow(release).to receive(:photo).and_return(photo)
|
||||
end
|
||||
end
|
||||
|
||||
def build_releases_with_photo_keys(keys)
|
||||
keys.map { |key| build_release_with_photo_key(key) }
|
||||
end
|
||||
end
|
||||
21
spec/models/import_spec.rb
Normal file
21
spec/models/import_spec.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Import do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:project) }
|
||||
it { is_expected.to belong_to(:releasable).optional }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to allow_content_type("application/pdf").for(:file) }
|
||||
it { is_expected.not_to allow_content_types("image/png", "image/jpeg").for(:file) }
|
||||
end
|
||||
|
||||
describe "enums" do
|
||||
it { is_expected.to define_enum_for(:status).with_values([:pending, :started, :finished, :failed]) }
|
||||
end
|
||||
|
||||
describe "#file" do
|
||||
it { is_expected.to respond_to(:file) }
|
||||
end
|
||||
end
|
||||
56
spec/models/location_release_spec.rb
Normal file
56
spec/models/location_release_spec.rb
Normal file
@@ -0,0 +1,56 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe LocationRelease do
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
it_behaves_like "a photoable"
|
||||
it_behaves_like "a releasable"
|
||||
it_behaves_like "a taggable"
|
||||
|
||||
describe "associations" do
|
||||
it { is_expected.to have_many(:video_release_confirmations).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
|
||||
it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
|
||||
|
||||
context "for native releases" do
|
||||
it { is_expected.to validate_presence_of(:person_first_name).on(:native) }
|
||||
it { is_expected.to validate_presence_of(:person_last_name).on(:native) }
|
||||
it { is_expected.to validate_attachment_of(:signature).on(:native) }
|
||||
end
|
||||
|
||||
it "ensures that film start date is before film end date" do
|
||||
location_release = build(:location_release, filming_started_on: 1.day.ago, filming_ended_on: 3.days.ago)
|
||||
|
||||
expect(location_release).not_to be_valid
|
||||
expect(location_release.errors[:filming_ended_on]).to include("must be after the filming started on date")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#uses_edl?" do
|
||||
it { is_expected.to be_uses_edl }
|
||||
end
|
||||
|
||||
describe "#contract_file_name" do
|
||||
it "includes project name, release type, signed at date, release number and location name" do
|
||||
release = create(:location_release_with_contract_template, name: "Benny's Burritos", signed_at: DateTime.new(2020, 2, 10, 12, 0, 0))
|
||||
|
||||
expect(release.contract_file_name).to eq("my-video-project_location_2020.02.10_1_benny-s-burritos")
|
||||
end
|
||||
|
||||
context "when signature timestamp is nil" do
|
||||
it "uses created at date" do
|
||||
release = create(:location_release_with_contract_template,
|
||||
name: "Benny's Burritos",
|
||||
signed_at: nil,
|
||||
created_at: DateTime.new(2020, 2, 10, 12, 0, 0))
|
||||
|
||||
expect(release.contract_file_name).to eq("my-video-project_location_2020.02.10_1_benny-s-burritos")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
46
spec/models/material_release_spec.rb
Normal file
46
spec/models/material_release_spec.rb
Normal file
@@ -0,0 +1,46 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe MaterialRelease do
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
it_behaves_like "a photoable"
|
||||
it_behaves_like "a releasable"
|
||||
it_behaves_like "a taggable"
|
||||
|
||||
describe "associations" do
|
||||
it { is_expected.to have_many(:video_release_confirmations).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
|
||||
it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
|
||||
|
||||
context "for native releases" do
|
||||
it { is_expected.to validate_presence_of(:person_first_name).on(:native) }
|
||||
it { is_expected.to validate_presence_of(:person_last_name).on(:native) }
|
||||
it { is_expected.to validate_attachment_of(:signature).on(:native) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "#uses_edl?" do
|
||||
it { is_expected.to be_uses_edl }
|
||||
end
|
||||
|
||||
describe "#contract_file_name" do
|
||||
it "includes project name, release type, signed at date, release number and release name" do
|
||||
release = create(:material_release_with_contract_template, name: "Coke", person_name: "John Doe", signed_at: DateTime.new(2020, 2, 10, 12, 0, 0))
|
||||
|
||||
expect(release.contract_file_name).to eq("my-video-project_material_2020.02.10_1_coke")
|
||||
end
|
||||
|
||||
context "when signer is not present" do
|
||||
it "includes created at date" do
|
||||
release = create(:material_release_with_contract_template, name: "Coke", person_name: "John Doe", created_at: DateTime.new(2020, 3, 10, 12, 0, 0))
|
||||
|
||||
expect(release.contract_file_name).to eq("my-video-project_material_2020.03.10_1_coke")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
94
spec/models/music_release_spec.rb
Normal file
94
spec/models/music_release_spec.rb
Normal file
@@ -0,0 +1,94 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe MusicRelease do
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
it_behaves_like "a releasable"
|
||||
it_behaves_like "a taggable"
|
||||
|
||||
describe "associations" do
|
||||
it { is_expected.to have_many(:file_infos).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:composers).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:publishers).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "nested attributes" do
|
||||
it { is_expected.to accept_nested_attributes_for(:file_infos) }
|
||||
it { is_expected.to accept_nested_attributes_for(:composers) }
|
||||
it { is_expected.to accept_nested_attributes_for(:publishers) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
|
||||
describe "#person_email" do
|
||||
it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
|
||||
it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
|
||||
end
|
||||
|
||||
describe "composers" do
|
||||
it "validates length 1" do
|
||||
music_release = build(:music_release)
|
||||
music_release.composers = []
|
||||
|
||||
expect(music_release.valid?).to eq false
|
||||
expect(music_release.errors[:composers]).to eq ["at least 1 required"]
|
||||
end
|
||||
|
||||
it "validates all percentages add up to 100" do
|
||||
music_release = build(:music_release, composers: [build(:composer, percentage: 55), build(:composer, percentage: 55)])
|
||||
|
||||
expect(music_release.valid?).to eq false
|
||||
expect(music_release.errors[:base]).to eq ["Composer percentages must add up to 100%"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "publishers" do
|
||||
it "validates length 1" do
|
||||
music_release = build(:music_release)
|
||||
music_release.publishers = []
|
||||
|
||||
expect(music_release.valid?).to eq false
|
||||
expect(music_release.errors[:publishers]).to eq ["at least 1 required"]
|
||||
end
|
||||
|
||||
it "validates all percentages add up to 100" do
|
||||
music_release = build(:music_release, publishers: [build(:publisher, percentage: 55), build(:publisher, percentage: 55)])
|
||||
|
||||
expect(music_release.valid?).to eq false
|
||||
expect(music_release.errors[:base]).to eq ["Publisher percentages must add up to 100%"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "attachments" do
|
||||
it { is_expected.to respond_to(:contract) }
|
||||
end
|
||||
|
||||
describe "#uses_edl?" do
|
||||
it { is_expected.to be_uses_edl }
|
||||
end
|
||||
|
||||
describe "#composer_info" do
|
||||
it "returns a single string with all the info included" do
|
||||
release = build(:music_release, composers: [
|
||||
build(:composer, name: "composer1", affiliation: "affiliation1", percentage: 50, cae_number: "cae1"),
|
||||
build(:composer, name: "composer2", affiliation: "affiliation2", percentage: 50, cae_number: "cae2"),
|
||||
])
|
||||
|
||||
expect(release.composer_info).to eq("composer1, affiliation1, 50.0, $cae:cae1|composer2, affiliation2, 50.0, $cae:cae2")
|
||||
end
|
||||
|
||||
context "when a cae number is present" do
|
||||
it "includes it in the info" do
|
||||
release = build(:music_release, composers: [
|
||||
build(:composer, name: "composer1", affiliation: "affiliation1", percentage: 50, cae_number: nil),
|
||||
build(:composer, name: "composer2", affiliation: "affiliation2", percentage: 50, cae_number: "cae2"),
|
||||
])
|
||||
|
||||
expect(release.composer_info).to eq("composer1, affiliation1, 50.0|composer2, affiliation2, 50.0, $cae:cae2")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
88
spec/models/mux_live_stream_spec.rb
Normal file
88
spec/models/mux_live_stream_spec.rb
Normal file
@@ -0,0 +1,88 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe MuxLiveStream, type: :model do
|
||||
let(:broadcast) { build(:broadcast, name: "My Broadcast") }
|
||||
let(:broadcast_2) { create(:broadcast, :with_stream, skip_create_callback: true, name: "My Broadcast") }
|
||||
let(:live_stream_data) { OpenStruct.new(data: OpenStruct.new(id: "stream_id", stream_key: "stream_key")) }
|
||||
let(:live_stream_playback_data) { OpenStruct.new(data: OpenStruct.new(id: "playback_id")) }
|
||||
|
||||
it "creates live stream and live stream playback URL" do
|
||||
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream).and_return(live_stream_data)
|
||||
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream_playback_id).and_return(live_stream_playback_data)
|
||||
|
||||
live_stream = MuxLiveStream.new
|
||||
|
||||
expect(live_stream.id).to eq "stream_id"
|
||||
expect(live_stream.key).to eq "stream_key"
|
||||
expect(live_stream.playback_id).to eq "playback_id"
|
||||
end
|
||||
|
||||
it "destroys live stream" do
|
||||
expect_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:delete_live_stream).with(broadcast_2.stream_uid)
|
||||
|
||||
stream = MuxLiveStream.new
|
||||
stream.destroy_stream(broadcast_2.stream_uid)
|
||||
end
|
||||
|
||||
context "when reduced latency is enabled via the environment" do
|
||||
it "turns on reduced latency mode when creating the live stream" do
|
||||
allow(ENV).to receive(:[]).with("MUX_REDUCED_LATENCY_ENABLED").and_return("true")
|
||||
allow(ENV).to receive(:[]).with("MUX_TEST_MODE_DISABLED").and_return("false")
|
||||
request = instance_double(MuxRuby::CreateLiveStreamRequest)
|
||||
allow(request).to receive(:reduced_latency=)
|
||||
allow(request).to receive(:new_asset_settings=)
|
||||
allow(request).to receive(:playback_policy=)
|
||||
allow(request).to receive(:test=)
|
||||
allow(MuxRuby::CreateLiveStreamRequest).to receive(:new).and_return(request)
|
||||
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream).and_return(live_stream_data)
|
||||
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream_playback_id).and_return(live_stream_playback_data)
|
||||
|
||||
live_stream = MuxLiveStream.new
|
||||
|
||||
expect(live_stream.id).to eq "stream_id"
|
||||
expect(request).to have_received(:reduced_latency=).with(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when test mode is enabled" do
|
||||
it "creates live streams in test mode" do
|
||||
allow(ENV).to receive(:[]).with("MUX_REDUCED_LATENCY_ENABLED").and_return("true")
|
||||
allow(ENV).to receive(:[]).with("MUX_TEST_MODE_DISABLED").and_return(nil)
|
||||
request = instance_double(MuxRuby::CreateLiveStreamRequest)
|
||||
allow(request).to receive(:reduced_latency=)
|
||||
allow(request).to receive(:new_asset_settings=)
|
||||
allow(request).to receive(:playback_policy=)
|
||||
allow(request).to receive(:test=)
|
||||
allow(MuxRuby::CreateLiveStreamRequest).to receive(:new).and_return(request)
|
||||
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream).and_return(live_stream_data)
|
||||
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream_playback_id).and_return(live_stream_playback_data)
|
||||
|
||||
live_stream = MuxLiveStream.new
|
||||
|
||||
expect(live_stream.id).to eq "stream_id"
|
||||
expect(request).to have_received(:reduced_latency=).with(true)
|
||||
expect(request).to have_received(:test=).with(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when test mode is disabled" do
|
||||
it "creates live streams in test mode" do
|
||||
allow(ENV).to receive(:[]).with("MUX_REDUCED_LATENCY_ENABLED").and_return("true")
|
||||
allow(ENV).to receive(:[]).with("MUX_TEST_MODE_DISABLED").and_return("true")
|
||||
request = instance_double(MuxRuby::CreateLiveStreamRequest)
|
||||
allow(request).to receive(:reduced_latency=)
|
||||
allow(request).to receive(:new_asset_settings=)
|
||||
allow(request).to receive(:playback_policy=)
|
||||
allow(request).to receive(:test=)
|
||||
allow(MuxRuby::CreateLiveStreamRequest).to receive(:new).and_return(request)
|
||||
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream).and_return(live_stream_data)
|
||||
allow_any_instance_of(MuxRuby::LiveStreamsApi).to receive(:create_live_stream_playback_id).and_return(live_stream_playback_data)
|
||||
|
||||
live_stream = MuxLiveStream.new
|
||||
|
||||
expect(live_stream.id).to eq "stream_id"
|
||||
expect(request).to have_received(:reduced_latency=).with(true)
|
||||
expect(request).to have_received(:test=).with(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
12
spec/models/note_spec.rb
Normal file
12
spec/models/note_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Note, type: :model do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:user).optional }
|
||||
it { is_expected.to belong_to(:notable) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:content) }
|
||||
end
|
||||
end
|
||||
381
spec/models/pending_analysis_spec.rb
Normal file
381
spec/models/pending_analysis_spec.rb
Normal file
@@ -0,0 +1,381 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe PendingAnalysis do
|
||||
describe '.poll' do
|
||||
it 'polls videos with pending video analysis' do
|
||||
allow(PendingAnalysis::PendingVideoAnalysis).to receive(:poll)
|
||||
|
||||
PendingAnalysis.poll
|
||||
|
||||
expect(PendingAnalysis::PendingVideoAnalysis).to have_received(:poll)
|
||||
end
|
||||
|
||||
it 'polls videos with pending audio analysis' do
|
||||
allow(PendingAnalysis::PendingAudioAnalysis).to receive(:poll)
|
||||
|
||||
PendingAnalysis.poll
|
||||
|
||||
expect(PendingAnalysis::PendingAudioAnalysis).to have_received(:poll)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.expire' do
|
||||
let(:age_threshold) { 2.days.ago }
|
||||
|
||||
it 'expires videos with pending video analysis' do
|
||||
allow(PendingAnalysis::PendingVideoAnalysis).to receive(:expire)
|
||||
|
||||
PendingAnalysis.expire(age_threshold)
|
||||
|
||||
expect(PendingAnalysis::PendingVideoAnalysis).to have_received(:expire).with(age_threshold)
|
||||
end
|
||||
|
||||
it 'expires videos with pending audio analysis' do
|
||||
allow(PendingAnalysis::PendingAudioAnalysis).to receive(:expire)
|
||||
|
||||
PendingAnalysis.expire(age_threshold)
|
||||
|
||||
expect(PendingAnalysis::PendingAudioAnalysis).to have_received(:expire).with(age_threshold)
|
||||
end
|
||||
end
|
||||
|
||||
describe PendingAnalysis::PendingVideoAnalysis do
|
||||
describe '.poll' do
|
||||
it 'polls all videos with pending analysis' do
|
||||
pending_analysis = create(:video, analysis_status: :pending, analysis_uid: "pending_uid")
|
||||
not_pending_analysis = create(:video, analysis_status: :success, analysis_uid: "not_pending_uid")
|
||||
|
||||
allow(described_class).to receive(:new).and_return(spy)
|
||||
|
||||
described_class.poll
|
||||
|
||||
expect(described_class).to have_received(:new).with("pending_uid")
|
||||
expect(described_class).not_to have_received(:new).with("not_pending_uid")
|
||||
end
|
||||
end
|
||||
|
||||
describe '.expire' do
|
||||
it 'expires all videos with pending analysis older than a given time' do
|
||||
pending_analysis_inside_range = create(:video,
|
||||
analysis_status: :pending,
|
||||
analysis_uid: "pending_inside_uid",
|
||||
analysis_started_at: 1.week.ago)
|
||||
pending_analysis_outside_range = create(:video,
|
||||
analysis_status: :pending,
|
||||
analysis_uid: "pending_outside_uid",
|
||||
analysis_started_at: 1.minute.ago)
|
||||
not_pending_analysis = create(:video,
|
||||
analysis_status: :success,
|
||||
analysis_uid: "not_pending_uid")
|
||||
|
||||
allow(described_class).to receive(:new).and_return(spy)
|
||||
|
||||
described_class.expire(1.day.ago)
|
||||
|
||||
expect(described_class).to have_received(:new).with("pending_inside_uid")
|
||||
expect(described_class).not_to have_received(:new).with("pending_outside_uid")
|
||||
expect(described_class).not_to have_received(:new).with("not_pending_uid")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#poll' do
|
||||
let(:video) { create(:video, analysis_status: :pending, analysis_uid: "analysis_uid") }
|
||||
|
||||
subject { PendingAnalysis::PendingVideoAnalysis.new(video.analysis_uid) }
|
||||
|
||||
context 'when API results are present' do
|
||||
it 'updates the video analysis status to success' do
|
||||
allow(BrayniacAI::FacialRecognition).to(
|
||||
receive(:find).and_return(BrayniacAI::FacialRecognition.new({ results: {} }))
|
||||
)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(video.reload).to be_analysis_success
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API results are not present' do
|
||||
it 'does nothing' do
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(video.reload).to be_analysis_pending
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API resource is not found' do
|
||||
it 'does nothing' do
|
||||
error = ActiveResource::ResourceNotFound.new('')
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(video.reload).to be_analysis_pending
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API server error occurs' do
|
||||
before do
|
||||
allow(Rails.logger).to receive(:error)
|
||||
allow(subject).to receive(:puts)
|
||||
end
|
||||
|
||||
it 'does nothing' do
|
||||
error = ActiveResource::ServerError.new('')
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(video.reload).to be_analysis_pending
|
||||
end
|
||||
|
||||
it 'prints error message to logger' do
|
||||
error = ActiveResource::ServerError.new('')
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(Rails.logger).to have_received(:error)
|
||||
expect(subject).to have_received(:puts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#expire' do
|
||||
let(:video) { create(:video, analysis_status: :pending, analysis_uid: "analysis_uid") }
|
||||
|
||||
subject { PendingAnalysis::PendingVideoAnalysis.new(video.analysis_uid) }
|
||||
|
||||
context 'when API results are present' do
|
||||
it 'updates the video analysis status to success' do
|
||||
allow(BrayniacAI::FacialRecognition).to(
|
||||
receive(:find).and_return(BrayniacAI::FacialRecognition.new({ results: {} }))
|
||||
)
|
||||
|
||||
subject.expire
|
||||
|
||||
expect(video.reload).to be_analysis_success
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API results are not present' do
|
||||
it 'updates the video analysis status to failure' do
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new)
|
||||
|
||||
subject.expire
|
||||
|
||||
expect(video.reload).to be_analysis_failure
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API resource is not found' do
|
||||
it 'updates the video analysis status to failure' do
|
||||
error = ActiveResource::ResourceNotFound.new('')
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.expire
|
||||
|
||||
expect(video.reload).to be_analysis_failure
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API server error occurs' do
|
||||
before do
|
||||
allow(Rails.logger).to receive(:error)
|
||||
allow(subject).to receive(:puts)
|
||||
end
|
||||
|
||||
it 'does nothing' do
|
||||
error = ActiveResource::ServerError.new('')
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(video.reload).to be_analysis_pending
|
||||
end
|
||||
|
||||
it 'prints error message to logger' do
|
||||
error = ActiveResource::ServerError.new('')
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(Rails.logger).to have_received(:error)
|
||||
expect(subject).to have_received(:puts)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe PendingAnalysis::PendingAudioAnalysis do
|
||||
describe '.poll' do
|
||||
it 'polls all videos with pending audio analysis' do
|
||||
pending_analysis = create(:video, audio_analysis_status: :pending, audio_analysis_uid: "pending_uid")
|
||||
not_pending_analysis = create(:video, audio_analysis_status: :success, audio_analysis_uid: "not_pending_uid")
|
||||
|
||||
allow(described_class).to receive(:new).and_return(spy)
|
||||
|
||||
described_class.poll
|
||||
|
||||
expect(described_class).to have_received(:new).with("pending_uid")
|
||||
expect(described_class).not_to have_received(:new).with("not_pending_uid")
|
||||
end
|
||||
end
|
||||
|
||||
describe '.expire' do
|
||||
it 'expires all videos with pending analysis older than a given time' do
|
||||
pending_analysis_inside_range = create(:video,
|
||||
audio_analysis_status: :pending,
|
||||
audio_analysis_uid: "pending_inside_uid",
|
||||
audio_analysis_started_at: 1.week.ago)
|
||||
pending_analysis_outside_range = create(:video,
|
||||
audio_analysis_status: :pending,
|
||||
audio_analysis_uid: "pending_outside_uid",
|
||||
audio_analysis_started_at: 1.minute.ago)
|
||||
not_pending_analysis = create(:video,
|
||||
analysis_status: :success,
|
||||
analysis_uid: "not_pending_uid")
|
||||
|
||||
allow(described_class).to receive(:new).and_return(spy)
|
||||
|
||||
described_class.expire(1.day.ago)
|
||||
|
||||
expect(described_class).to have_received(:new).with("pending_inside_uid")
|
||||
expect(described_class).not_to have_received(:new).with("pending_outside_uid")
|
||||
expect(described_class).not_to have_received(:new).with("not_pending_uid")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#poll' do
|
||||
let(:video) { create(:video, audio_analysis_status: :pending, audio_analysis_uid: "analysis_uid") }
|
||||
|
||||
subject { PendingAnalysis::PendingAudioAnalysis.new(video.audio_analysis_uid) }
|
||||
|
||||
context 'when API results are present' do
|
||||
it 'updates the audio analysis status to success' do
|
||||
allow(BrayniacAI::AudioRecognition).to(
|
||||
receive(:find).and_return(OpenStruct.new({ results: {} }))
|
||||
)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(video.reload).to be_audio_analysis_success
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API results are not present' do
|
||||
it 'does nothing' do
|
||||
allow(BrayniacAI::AudioRecognition).to receive(:find).and_return(BrayniacAI::AudioRecognition.new)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(video.reload).to be_audio_analysis_pending
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API resource is not found' do
|
||||
it 'does nothing' do
|
||||
error = ActiveResource::ResourceNotFound.new('')
|
||||
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(video.reload).to be_audio_analysis_pending
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API server error occurs' do
|
||||
before do
|
||||
allow(Rails.logger).to receive(:error)
|
||||
allow(subject).to receive(:puts)
|
||||
end
|
||||
|
||||
it 'does nothing' do
|
||||
error = ActiveResource::ServerError.new('')
|
||||
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(video.reload).to be_audio_analysis_pending
|
||||
end
|
||||
|
||||
it 'prints error message to logger' do
|
||||
error = ActiveResource::ServerError.new('')
|
||||
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(Rails.logger).to have_received(:error)
|
||||
expect(subject).to have_received(:puts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#expire' do
|
||||
let(:video) { create(:video, audio_analysis_status: :pending, audio_analysis_uid: "analysis_uid") }
|
||||
|
||||
subject { PendingAnalysis::PendingAudioAnalysis.new(video.audio_analysis_uid) }
|
||||
|
||||
context 'when API results are present' do
|
||||
it 'updates the audio analysis status to success' do
|
||||
allow(BrayniacAI::AudioRecognition).to(
|
||||
receive(:find).and_return(BrayniacAI::AudioRecognition.new({ results: {} }))
|
||||
)
|
||||
|
||||
subject.expire
|
||||
|
||||
expect(video.reload).to be_audio_analysis_success
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API results are not present' do
|
||||
it 'updates the audio analysis status to failure' do
|
||||
allow(BrayniacAI::AudioRecognition).to receive(:find).and_return(BrayniacAI::AudioRecognition.new)
|
||||
|
||||
subject.expire
|
||||
|
||||
expect(video.reload).to be_audio_analysis_failure
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API resource is not found' do
|
||||
it 'updates the audio analysis status to failure' do
|
||||
error = ActiveResource::ResourceNotFound.new('')
|
||||
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.expire
|
||||
|
||||
expect(video.reload).to be_audio_analysis_failure
|
||||
end
|
||||
end
|
||||
|
||||
context 'when API server error occurs' do
|
||||
before do
|
||||
allow(Rails.logger).to receive(:error)
|
||||
allow(subject).to receive(:puts)
|
||||
end
|
||||
|
||||
it 'does nothing' do
|
||||
error = ActiveResource::ServerError.new('')
|
||||
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(video.reload).to be_audio_analysis_pending
|
||||
end
|
||||
|
||||
it 'prints error message to logger' do
|
||||
error = ActiveResource::ServerError.new('')
|
||||
allow(BrayniacAI::AudioRecognition).to receive(:find).and_raise(error)
|
||||
|
||||
subject.poll
|
||||
|
||||
expect(Rails.logger).to have_received(:error)
|
||||
expect(subject).to have_received(:puts)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
168
spec/models/project_membership_spec.rb
Normal file
168
spec/models/project_membership_spec.rb
Normal file
@@ -0,0 +1,168 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe ProjectMembership, type: :model do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:project) }
|
||||
it { is_expected.to belong_to(:user) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
describe "#user_id" do
|
||||
subject do
|
||||
account = build(:account)
|
||||
build(:project_membership,
|
||||
user: build(:user, primary_account: account),
|
||||
project: build(:project, account: account))
|
||||
end
|
||||
it { is_expected.to validate_uniqueness_of(:user_id).scoped_to(:project_id).with_message("already belongs to this Project") }
|
||||
end
|
||||
|
||||
it "does not allow account managers" do
|
||||
account = build(:account)
|
||||
account_manager = create(:user, :account_manager, accounts: [account])
|
||||
project = build(:project, account: account)
|
||||
|
||||
project_membership = ProjectMembership.new(user: account_manager, project: project)
|
||||
|
||||
expect(project_membership).to be_invalid
|
||||
expect(project_membership.errors[:user]).not_to be_empty
|
||||
expect(project_membership.errors.full_messages.first).to eq "User is already an account manager"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#save_and_update_account_membership" do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
context "when no user exists for the given email" do
|
||||
let(:membership) { ProjectMembership.new(project: project, user_email: "new.user@test.com") }
|
||||
|
||||
it "returns true" do
|
||||
expect(membership.save_and_update_account_membership).to be_truthy
|
||||
end
|
||||
|
||||
it "creates the user" do
|
||||
expect {
|
||||
membership.save_and_update_account_membership
|
||||
}.to change(User, :count).by(1)
|
||||
|
||||
user = User.last
|
||||
|
||||
expect(user.email).to eq "new.user@test.com"
|
||||
end
|
||||
|
||||
it "creates account membership" do
|
||||
expect {
|
||||
membership.save_and_update_account_membership
|
||||
}.to change(AccountAuth, :count).by(1)
|
||||
|
||||
account_auth = AccountAuth.last
|
||||
user = User.last
|
||||
|
||||
expect(account_auth.account).to eq project.account
|
||||
expect(account_auth.user).to eq user
|
||||
end
|
||||
|
||||
it "creates project membership" do
|
||||
expect {
|
||||
membership.save_and_update_account_membership
|
||||
}.to change(ProjectMembership, :count).by(1)
|
||||
|
||||
user = User.last
|
||||
|
||||
expect(membership.project).to eq project
|
||||
expect(membership.user).to eq user
|
||||
end
|
||||
end
|
||||
|
||||
context "when user exists but has no account access" do
|
||||
let!(:user) { create(:user, email: "existing.user@test.com") }
|
||||
let(:membership) { ProjectMembership.new(project: project, user_email: "existing.user@test.com") }
|
||||
|
||||
it "returns true" do
|
||||
expect(membership.save_and_update_account_membership).to be_truthy
|
||||
end
|
||||
|
||||
it "creates account membership" do
|
||||
expect {
|
||||
membership.save_and_update_account_membership
|
||||
}.to change(AccountAuth, :count).by(1)
|
||||
|
||||
account_auth = AccountAuth.last
|
||||
|
||||
expect(account_auth.account).to eq project.account
|
||||
expect(account_auth.user).to eq user
|
||||
end
|
||||
|
||||
it "creates project membership" do
|
||||
expect {
|
||||
membership.save_and_update_account_membership
|
||||
}.to change(ProjectMembership, :count).by(1)
|
||||
|
||||
expect(membership.project).to eq project
|
||||
expect(membership.user).to eq user
|
||||
end
|
||||
end
|
||||
|
||||
context "when user exists and has account access" do
|
||||
let!(:user) { create(:user, email: "existing.user@test.com", accounts: [project.account]) }
|
||||
let(:membership) { ProjectMembership.new(project: project, user_email: "existing.user@test.com") }
|
||||
|
||||
it "returns true" do
|
||||
expect(membership.save_and_update_account_membership).to be_truthy
|
||||
end
|
||||
|
||||
it "creates project membership" do
|
||||
expect {
|
||||
membership.save_and_update_account_membership
|
||||
}.to change(ProjectMembership, :count).by(1)
|
||||
|
||||
expect(membership.project).to eq project
|
||||
expect(membership.user).to eq user
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples "creates no records and returns false" do
|
||||
it "returns false" do
|
||||
expect(membership.save_and_update_account_membership).to be_falsey
|
||||
end
|
||||
|
||||
it "does not create new records" do
|
||||
expect { membership.save_and_update_account_membership }.
|
||||
to change(ProjectMembership, :count).by(0).
|
||||
and change(AccountAuth, :count).by(0).
|
||||
and change(User, :count).by(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "when user cannot be saved" do
|
||||
let(:membership) { ProjectMembership.new(project: project, user_email: "new.user@test.com") }
|
||||
|
||||
before do
|
||||
allow_any_instance_of(Oath::Services::SignUp).to receive(:perform).and_return(build(:user))
|
||||
allow_any_instance_of(User).to receive(:save).and_return(false)
|
||||
end
|
||||
|
||||
include_examples "creates no records and returns false"
|
||||
end
|
||||
|
||||
context "when account auth cannot be saved" do
|
||||
let(:membership) { ProjectMembership.new(project: project, user_email: "new.user@test.com") }
|
||||
|
||||
before do
|
||||
allow_any_instance_of(AccountAuth).to receive(:save).and_return(false)
|
||||
end
|
||||
|
||||
include_examples "creates no records and returns false"
|
||||
end
|
||||
|
||||
context "when project membership cannot be saved" do
|
||||
let(:membership) { ProjectMembership.new(project: project, user_email: "new.user@test.com") }
|
||||
|
||||
before do
|
||||
allow_any_instance_of(ProjectMembership).to receive(:save).and_return(false)
|
||||
end
|
||||
|
||||
include_examples "creates no records and returns false"
|
||||
end
|
||||
end
|
||||
end
|
||||
117
spec/models/project_spec.rb
Normal file
117
spec/models/project_spec.rb
Normal file
@@ -0,0 +1,117 @@
|
||||
require "rails_helper"
|
||||
require "zoom_gateway"
|
||||
|
||||
RSpec.describe Project, type: :model do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:account) }
|
||||
it { is_expected.to have_many(:acquired_media_releases).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:appearance_releases).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:location_releases).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:material_releases).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:music_releases).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:talent_releases).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:videos).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:contract_templates).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:project_memberships).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:users).through(:project_memberships) }
|
||||
it { is_expected.to have_many(:directories).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:broadcasts).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:downloads).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:zoom_meetings).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "nested attributes" do
|
||||
it { is_expected.to accept_nested_attributes_for(:project_memberships) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
|
||||
describe "#name uniqueness validation" do
|
||||
subject { build(:project) }
|
||||
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:account_id) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "#import_contract_templates" do
|
||||
it "imports contract templates from other projects within the account" do
|
||||
existing_project = create(:project_with_contract_template)
|
||||
new_project = create(:project, name: "New Project", account: existing_project.account)
|
||||
|
||||
expect {
|
||||
expect(new_project.import_contract_templates(existing_project.contract_templates.pluck(:id))).to be_truthy
|
||||
}.to change(ContractTemplate, :count).by(1)
|
||||
|
||||
expect(new_project.reload.contract_templates.size).to eq(1)
|
||||
expect(new_project.contract_templates.first.body.to_s).to eq(existing_project.contract_templates.first.body.to_s)
|
||||
expect(new_project.contract_templates.first.guardian_clause.to_s).to eq(existing_project.contract_templates.first.guardian_clause.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#members" do
|
||||
it "returns users who have membership to the project and account managers" do
|
||||
account = build(:account)
|
||||
account_manager = create(:user, :account_manager, primary_account: account)
|
||||
associate = create(:user, :associate, primary_account: account)
|
||||
project = create(:project, members: associate, account: account)
|
||||
|
||||
members = project.members
|
||||
|
||||
expect(members).to include(associate)
|
||||
expect(members).to include(account_manager)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#zoom_meeting' do
|
||||
before(:all) do
|
||||
WebMock.disable_net_connect!(allow_localhost: true)
|
||||
end
|
||||
|
||||
let(:project) { create(:project) }
|
||||
|
||||
context 'there is a meeting already going' do
|
||||
let!(:zoom_meeting) { create(:zoom_meeting, status: :started, project: project, api_meeting_id: 'meeting-id') }
|
||||
|
||||
it 'returns the active meeting' do
|
||||
expect(project.zoom_meeting).to eq(zoom_meeting)
|
||||
end
|
||||
end
|
||||
|
||||
context 'there is no meeting' do
|
||||
context 'there is a free user available' do
|
||||
let!(:free_zoom_user) { create(:zoom_user, api_id: 'user_id') }
|
||||
|
||||
before do
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return('new-meeting-id')
|
||||
end
|
||||
|
||||
it 'creates new meeting' do
|
||||
expect { project.zoom_meeting }.to change { ZoomMeeting.count }.by(1)
|
||||
end
|
||||
|
||||
it 'returns new meeting' do
|
||||
expect(project.zoom_meeting.api_meeting_id).to eq('new-meeting-id')
|
||||
end
|
||||
end
|
||||
|
||||
context 'there is no free user available' do
|
||||
before do
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return('new-host-id')
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return('new-meeting-id')
|
||||
end
|
||||
|
||||
it 'creates new user' do
|
||||
expect { project.zoom_meeting }.to change { ZoomUser.count }.by(1)
|
||||
end
|
||||
|
||||
it 'creates new meeting' do
|
||||
expect { project.zoom_meeting }.to change { ZoomMeeting.count }.by(1)
|
||||
end
|
||||
|
||||
it 'returns new meeting' do
|
||||
expect(project.zoom_meeting.api_meeting_id).to eq('new-meeting-id')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
9
spec/models/publisher_spec.rb
Normal file
9
spec/models/publisher_spec.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Publisher do
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
it { is_expected.to validate_presence_of(:affiliation) }
|
||||
it { is_expected.to validate_presence_of(:percentage) }
|
||||
end
|
||||
end
|
||||
21
spec/models/releasable_param_spec.rb
Normal file
21
spec/models/releasable_param_spec.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe ReleasableParam do
|
||||
describe "#id" do
|
||||
it "returns id from first releasable param" do
|
||||
expect(described_class.new({location_release_id: 1, talent_release_id: 4, another: "param"}).id).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "#name" do
|
||||
it "returns name from first releasable param" do
|
||||
expect(described_class.new({location_release_id: 1, talent_release_id: 4, another: "param"}).name).to eq "location_release"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#type" do
|
||||
it "returns type from first releasable param" do
|
||||
expect(described_class.new({location_release_id: 1, talent_release_id: 4, another: "param"}).type).to eq LocationRelease
|
||||
end
|
||||
end
|
||||
end
|
||||
54
spec/models/release_number_spec.rb
Normal file
54
spec/models/release_number_spec.rb
Normal file
@@ -0,0 +1,54 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ReleaseNumber, type: :model do
|
||||
let(:project) { create(:project) }
|
||||
|
||||
describe 'value' do
|
||||
it 'returns a number corresponding to the order in which the release was signed within the project' do
|
||||
later = create(:appearance_release, signed_at: 1.days.ago, project: project)
|
||||
earlier = create(:appearance_release, signed_at: 2.day.ago, project: project)
|
||||
|
||||
expect(release_number_for(earlier)).to eq 1
|
||||
expect(release_number_for(later)).to eq 2
|
||||
end
|
||||
|
||||
it 'does not count other release types' do
|
||||
appearance = create(:appearance_release, project: project)
|
||||
talent = create(:talent_release, project: project)
|
||||
|
||||
expect(release_number_for(appearance)).to eq 1
|
||||
expect(release_number_for(talent)).to eq 1
|
||||
end
|
||||
|
||||
it 'returns 1 if there are no saved releases' do
|
||||
appearance = build(:appearance_release, project: project)
|
||||
expect(release_number_for(appearance)).to eq 1
|
||||
end
|
||||
|
||||
it 'does not count releases from other projects' do
|
||||
my_appearance = create(:appearance_release, project: project)
|
||||
their_appearance = create(:appearance_release, project: build(:project))
|
||||
|
||||
expect(release_number_for(my_appearance)).to eq 1
|
||||
expect(release_number_for(their_appearance)).to eq 1
|
||||
end
|
||||
|
||||
it 'uses creation timestamp when signed timestamp is not present' do
|
||||
third = create(:appearance_release, signed_at: 1.day.ago, created_at: Time.zone.now, project: project)
|
||||
second = create(:appearance_release, signed_at: nil, created_at: 2.days.ago, project: project)
|
||||
first = create(:appearance_release, signed_at: 3.days.ago, created_at: Time.zone.now, project: project)
|
||||
|
||||
expect(release_number_for(first)).to eq 1
|
||||
expect(release_number_for(second)).to eq 2
|
||||
expect(release_number_for(third)).to eq 3
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def release_number_for(release)
|
||||
ReleaseNumber.new(release).value
|
||||
end
|
||||
end
|
||||
5
spec/models/restriction_spec.rb
Normal file
5
spec/models/restriction_spec.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Restriction, type: :model do
|
||||
it_behaves_like "a freeformable"
|
||||
end
|
||||
12
spec/models/sample_project_spec.rb
Normal file
12
spec/models/sample_project_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe SampleProject do
|
||||
describe '#new' do
|
||||
it 'returns a new Project record with filled-in data' do
|
||||
project = SampleProject.new
|
||||
attrs = %w(name client_name producer_name producer_address details description)
|
||||
|
||||
attrs.all? { |attr| expect(project.send(attr)).to be_present }
|
||||
end
|
||||
end
|
||||
end
|
||||
75
spec/models/talent_release_spec.rb
Normal file
75
spec/models/talent_release_spec.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe TalentRelease do
|
||||
it_behaves_like "a contractable"
|
||||
it_behaves_like "an exploitable"
|
||||
it_behaves_like "a notable"
|
||||
it_behaves_like "a photoable"
|
||||
it_behaves_like "a releasable"
|
||||
it_behaves_like "a taggable"
|
||||
|
||||
describe "associations" do
|
||||
it { is_expected.to have_many(:video_release_confirmations).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:confirmed_videos).source(:video).through(:video_release_confirmations) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:person_first_name) }
|
||||
it { is_expected.to validate_presence_of(:person_last_name) }
|
||||
|
||||
it "requires one or more photo" do
|
||||
talent_release = build(:talent_release, photos: [])
|
||||
expect(talent_release).not_to be_valid
|
||||
expect(talent_release.errors[:photos]).to include("must be included")
|
||||
end
|
||||
|
||||
context "for #person_email" do
|
||||
it { is_expected.to allow_value("test@test.com", nil).for(:person_email) }
|
||||
it { is_expected.not_to allow_values("foo", "test@foo", "N/A").for(:person_email) }
|
||||
end
|
||||
|
||||
context "for native releases" do
|
||||
it { is_expected.to validate_presence_of(:person_phone).on(:native) }
|
||||
it { is_expected.to validate_attachment_of(:signature).on(:native) }
|
||||
end
|
||||
|
||||
context "for non-native releases" do
|
||||
it { is_expected.to validate_attachment_of(:contract).on(:non_native) }
|
||||
end
|
||||
|
||||
context "when the signer is a minor" do
|
||||
subject { build(:talent_release, :minor) }
|
||||
|
||||
it { is_expected.to validate_presence_of(:guardian_first_name) }
|
||||
it { is_expected.to validate_presence_of(:guardian_last_name) }
|
||||
it { is_expected.to validate_presence_of(:guardian_phone) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "attachments" do
|
||||
it { is_expected.to respond_to(:signature) }
|
||||
end
|
||||
|
||||
describe "#uses_edl?" do
|
||||
it { is_expected.not_to be_uses_edl }
|
||||
end
|
||||
|
||||
describe "#contract_file_name" do
|
||||
it "includes project name, signed at date, release type, release number and person name" do
|
||||
release = create(:talent_release_with_contract_template, id: 100, signed_at: Date.new(2020, 2, 10), person_first_name: "John", person_last_name: "Doe")
|
||||
|
||||
expect(release.contract_file_name).to eq("my-video-project_talent_2020.02.10_1_doe-john")
|
||||
end
|
||||
|
||||
context "when signed at is nil" do
|
||||
it "uses the created at date" do
|
||||
release = create(:talent_release_with_contract_template,
|
||||
signed_at: nil,
|
||||
created_at: DateTime.new(2020, 2, 10, 12, 0, 0),
|
||||
person_first_name: "John", person_last_name: "Doe")
|
||||
|
||||
expect(release.contract_file_name).to eq("my-video-project_talent_2020.02.10_1_doe-john")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
5
spec/models/term_spec.rb
Normal file
5
spec/models/term_spec.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Term, type: :model do
|
||||
it_behaves_like "a freeformable"
|
||||
end
|
||||
5
spec/models/territory_spec.rb
Normal file
5
spec/models/territory_spec.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Territory, type: :model do
|
||||
it_behaves_like "a freeformable"
|
||||
end
|
||||
39
spec/models/unreleased_appearance_spec.rb
Normal file
39
spec/models/unreleased_appearance_spec.rb
Normal file
@@ -0,0 +1,39 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe UnreleasedAppearance do
|
||||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:video) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it do
|
||||
is_expected.to validate_presence_of(:time_elapsed)
|
||||
is_expected.to validate_presence_of(:note_category)
|
||||
end
|
||||
end
|
||||
|
||||
describe "enums" do
|
||||
it { is_expected.to define_enum_for(:note_category).with_values([:other, :missing_talent_release, :missing_appearance_release, :missing_location_release, :missing_acquired_media_license, :missing_materials_release, :missing_music_license, :logo_may_require_blurring]) }
|
||||
end
|
||||
|
||||
describe ".note_text" do
|
||||
let(:unreleased_appearance) do
|
||||
create(:unreleased_appearance)
|
||||
end
|
||||
|
||||
it "returns notes field in case category is 'other'" do
|
||||
unreleased_appearance.notes = "good note"
|
||||
result = unreleased_appearance.note_text
|
||||
expect(result).to eq "good note"
|
||||
end
|
||||
|
||||
it "returns human readable predefined value if category is not 'other'" do
|
||||
UnreleasedAppearance.note_categories.each_pair do |category, value|
|
||||
next if category == 'other'
|
||||
unreleased_appearance.note_category = category
|
||||
result = unreleased_appearance.note_text
|
||||
expect(result).to eq unreleased_appearance.note_category.humanize
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
153
spec/models/user_spec.rb
Normal file
153
spec/models/user_spec.rb
Normal file
@@ -0,0 +1,153 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe User, type: :model do
|
||||
describe "associations" do
|
||||
it { is_expected.to have_many(:accounts).through(:account_auths) }
|
||||
it { is_expected.to have_many(:account_auths).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:project_memberships).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it { is_expected.to validate_presence_of(:email) }
|
||||
it { is_expected.to validate_presence_of(:password_digest) }
|
||||
it { is_expected.to validate_presence_of(:time_zone) }
|
||||
|
||||
describe "#email uniqueness validation" do
|
||||
subject { build(:user) }
|
||||
it { is_expected.to validate_uniqueness_of(:email) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "#associate?" do
|
||||
it "returns true if the user is an associate for the given account" do
|
||||
account_auth = create(:account_auth, role: :associate)
|
||||
user = account_auth.user
|
||||
account = account_auth.account
|
||||
|
||||
expect(user.associate?(account)).to be_truthy
|
||||
end
|
||||
|
||||
context "when user does not belong to the given account" do
|
||||
it "raises an error" do
|
||||
account = build(:account)
|
||||
user = build(:user)
|
||||
|
||||
expect { user.associate?(account) }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#manager?" do
|
||||
it "returns true if the user is a project manager for the given account" do
|
||||
account_auth = create(:account_auth, role: :project_manager)
|
||||
user = account_auth.user
|
||||
account = account_auth.account
|
||||
|
||||
expect(user.manager?(account)).to be_truthy
|
||||
end
|
||||
|
||||
context "when user does not belong to the given account" do
|
||||
it "raises an error" do
|
||||
account = build(:account)
|
||||
user = build(:user)
|
||||
|
||||
expect { user.manager?(account) }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#account_manager?" do
|
||||
it "returns true if the user is an account manager for the given account" do
|
||||
account_auth = create(:account_auth, role: :account_manager)
|
||||
user = account_auth.user
|
||||
account = account_auth.account
|
||||
|
||||
expect(user.account_manager?(account)).to be_truthy
|
||||
end
|
||||
|
||||
context "when user does not belong to the given account" do
|
||||
it "raises an error" do
|
||||
account = build(:account)
|
||||
user = build(:user)
|
||||
|
||||
expect { user.account_manager?(account) }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#role_for" do
|
||||
it "returns the name of the role for the given account" do
|
||||
account_auth = create(:account_auth, role: :associate)
|
||||
user = account_auth.user
|
||||
account = account_auth.account
|
||||
|
||||
expect(user.role_for(account)).to eq "associate"
|
||||
|
||||
account_auth.update(role: :project_manager)
|
||||
expect(user.role_for(account)).to eq "project_manager"
|
||||
|
||||
account_auth.update(role: :account_manager)
|
||||
expect(user.role_for(account)).to eq "account_manager"
|
||||
end
|
||||
|
||||
context "when the user does not belong to the given account" do
|
||||
it "raises an error" do
|
||||
account = build(:account)
|
||||
user = build(:user)
|
||||
|
||||
expect { user.role_for(account) }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#primary_account" do
|
||||
it "returns the first account the user has access to" do
|
||||
user = build(:user, accounts: build_list(:account, 2))
|
||||
|
||||
expect(user.primary_account).to eq user.primary_account
|
||||
end
|
||||
|
||||
it "adds a given account to the collection" do
|
||||
account = build(:account)
|
||||
user = build(:user, accounts: [])
|
||||
|
||||
user.primary_account = account
|
||||
|
||||
expect(user.accounts).to include account
|
||||
end
|
||||
end
|
||||
|
||||
describe "#accessible_projects_for" do
|
||||
context "when user is an account manager" do
|
||||
it "returns all projects belonging to that account" do
|
||||
account = create(:account)
|
||||
account_manager = create(:user, :account_manager, primary_account: account)
|
||||
member_project = create(:project, name: "Member Project", account: account)
|
||||
non_member_project = create(:project, name: "Non-Member Project", account: account)
|
||||
outside_project = create(:project, name: "Outside Project", account: build(:account))
|
||||
|
||||
results = account_manager.accessible_projects_for(account)
|
||||
|
||||
expect(results).to include(member_project)
|
||||
expect(results).to include(non_member_project)
|
||||
expect(results).not_to include(outside_project)
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not an account manager" do
|
||||
it "returns all projects for which the user has a membership" do
|
||||
account = create(:account)
|
||||
associate = create(:user, :associate, primary_account: account)
|
||||
member_project = create(:project, members: associate, name: "Member Project", account: account)
|
||||
non_member_project = create(:project, members: [], name: "Non-Member Project", account: account)
|
||||
outside_project = create(:project, name: "Outside Project", account: build(:account))
|
||||
|
||||
results = associate.accessible_projects_for(account)
|
||||
|
||||
expect(results).to include(member_project)
|
||||
expect(results).not_to include(non_member_project)
|
||||
expect(results).not_to include(outside_project)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
120
spec/models/video_analysis_spec.rb
Normal file
120
spec/models/video_analysis_spec.rb
Normal file
@@ -0,0 +1,120 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe VideoAnalysis do
|
||||
let(:project) { create(:project, headshot_collection_uid: "collection_id") }
|
||||
let(:video) { create(:video, project: project) }
|
||||
|
||||
before :each do
|
||||
video.file.update(key: "generated-key")
|
||||
end
|
||||
|
||||
describe "#to_hash" do
|
||||
context "when reanalysis is true" do
|
||||
it "returns hash of bucket_name, collection_id, video_object_name, reanalysis" do
|
||||
allow(ENV).to receive(:[])
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("video-dumping-ground")
|
||||
|
||||
expect(described_class.new(video, true).to_hash).to eq({
|
||||
bucket_name: "video-dumping-ground",
|
||||
collection_id: "collection_id",
|
||||
video_object_name: "generated-key",
|
||||
reanalysis: true,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
context "when reanalysis is not true" do
|
||||
it "returns hash of bucket_name, collection_id, video_object_name" do
|
||||
allow(ENV).to receive(:[])
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("video-dumping-ground")
|
||||
|
||||
expect(described_class.new(video, false).to_hash).to eq({
|
||||
bucket_name: "video-dumping-ground",
|
||||
collection_id: "collection_id",
|
||||
video_object_name: "generated-key",
|
||||
reanalysis: false,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#as_json" do
|
||||
context "when reanalysis is true" do
|
||||
it "returns json with bucket_name, collection_id, video_object_name, reanalysis" do
|
||||
allow(ENV).to receive(:[])
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("video-dumping-ground")
|
||||
|
||||
expect(described_class.new(video, true).as_json).to eq({
|
||||
bucket_name: "video-dumping-ground",
|
||||
collection_id: "collection_id",
|
||||
video_object_name: "generated-key",
|
||||
reanalysis: true,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
context "when reanalysis is not true" do
|
||||
it "returns json with bucket_name, collection_id, video_object_name" do
|
||||
allow(ENV).to receive(:[])
|
||||
allow(ENV).to receive(:[]).with("AWS_BUCKET").and_return("video-dumping-ground")
|
||||
|
||||
expect(described_class.new(video, false).as_json).to eq({
|
||||
bucket_name: "video-dumping-ground",
|
||||
collection_id: "collection_id",
|
||||
video_object_name: "generated-key",
|
||||
reanalysis: false,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#overlay_video_url" do
|
||||
let(:video_analysis) { described_class.new(video, false) }
|
||||
|
||||
context "when use_overlay_video false" do
|
||||
before :each do
|
||||
video_analysis.use_overlay_video = false
|
||||
end
|
||||
|
||||
it "returns nil" do
|
||||
expect(video_analysis.overlay_video_url).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when use_overlay_video true" do
|
||||
before :each do
|
||||
video_analysis.use_overlay_video = true
|
||||
end
|
||||
|
||||
context "when overlay_video_url is None" do
|
||||
before :each do
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new({overlay_video_url: "None"}))
|
||||
end
|
||||
|
||||
it "returns nil" do
|
||||
expect(video_analysis.overlay_video_url).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "when overlay_video_url is not None" do
|
||||
before :each do
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new({overlay_video_url: "www.google.com"}))
|
||||
end
|
||||
|
||||
it "returns overlay_video_url" do
|
||||
expect(video_analysis.overlay_video_url).to eq "www.google.com"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#first_appearances" do
|
||||
before :each do
|
||||
allow(BrayniacAI::FacialRecognition).to receive(:find).and_return(BrayniacAI::FacialRecognition.new({first_appearances: ["appearance 1"]}))
|
||||
end
|
||||
|
||||
it "returns first_appearances from response" do
|
||||
expect(described_class.new(video, false).first_appearances).to eq ["appearance 1"]
|
||||
end
|
||||
end
|
||||
end
|
||||
15
spec/models/video_release_confirmation_spec.rb
Normal file
15
spec/models/video_release_confirmation_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe VideoReleaseConfirmation do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:releasable) }
|
||||
it { is_expected.to belong_to(:video) }
|
||||
it { is_expected.to belong_to(:file_info).optional }
|
||||
end
|
||||
|
||||
describe "#appears_at" do
|
||||
it "returns timecode string from time_elapsed" do
|
||||
expect(described_class.new(time_elapsed: "5").appears_at).to eq "00:00:05:00"
|
||||
end
|
||||
end
|
||||
end
|
||||
70
spec/models/video_spec.rb
Normal file
70
spec/models/video_spec.rb
Normal file
@@ -0,0 +1,70 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe Video do
|
||||
describe "associations" do
|
||||
it { is_expected.to belong_to(:project).touch(true) }
|
||||
it { is_expected.to have_many(:appearance_releases) }
|
||||
it { is_expected.to have_many(:location_releases) }
|
||||
it { is_expected.to have_many(:material_releases) }
|
||||
it { is_expected.to have_many(:talent_releases) }
|
||||
it { is_expected.to have_many(:bookmarks).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:video_release_confirmations).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:unreleased_appearances).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:confirmed_talent_releases).source(:releasable).through(:video_release_confirmations) }
|
||||
it { is_expected.to have_many(:confirmed_appearance_releases).source(:releasable).through(:video_release_confirmations) }
|
||||
it { is_expected.to have_many(:confirmed_location_releases).source(:releasable).through(:video_release_confirmations) }
|
||||
it { is_expected.to have_many(:confirmed_material_releases).source(:releasable).through(:video_release_confirmations) }
|
||||
it { is_expected.to have_many(:confirmed_talent_releases).source(:releasable).through(:video_release_confirmations) }
|
||||
it { is_expected.to have_many(:confirmed_acquired_media_releases).source(:releasable).through(:video_release_confirmations) }
|
||||
it { is_expected.to have_many(:graphics_elements).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:audio_confirmations).dependent(:destroy) }
|
||||
end
|
||||
|
||||
describe "attachments" do
|
||||
it { is_expected.to respond_to(:file) }
|
||||
it { is_expected.to respond_to(:edl_file) }
|
||||
it { is_expected.to respond_to(:graphics_only_edl_file) }
|
||||
it { is_expected.to respond_to(:audio_only_edl_file) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
context '#file' do
|
||||
it { is_expected.to validate_attachment_of(:file) }
|
||||
it { is_expected.to allow_content_type("video/mp4", "video/quicktime").for(:file) }
|
||||
it { is_expected.not_to allow_content_types("image/png").for(:file) }
|
||||
end
|
||||
|
||||
context '#edl_file' do
|
||||
it { is_expected.to validate_attachment_of(:edl_file) }
|
||||
it { is_expected.to allow_content_type("application/octet-stream").for(:edl_file) }
|
||||
it { is_expected.not_to allow_content_types("text/plain", "image/png", "image/jpeg").for(:edl_file) }
|
||||
end
|
||||
|
||||
context '#graphics_only_edl_file' do
|
||||
it { is_expected.to allow_content_type("application/octet-stream").for(:graphics_only_edl_file) }
|
||||
it { is_expected.not_to allow_content_types("text/plain", "image/png", "image/jpeg").for(:graphics_only_edl_file) }
|
||||
end
|
||||
|
||||
context '#audio_only_edl_file' do
|
||||
context "when video_editing_system is adobe_premiere" do
|
||||
subject { build(:video, video_editing_system: "adobe_premiere") }
|
||||
|
||||
it { is_expected.to validate_attachment_of(:audio_only_edl_file) }
|
||||
it { is_expected.to allow_content_type("application/octet-stream").for(:audio_only_edl_file) }
|
||||
it { is_expected.not_to allow_content_types("text/plain", "image/png", "image/jpeg").for(:audio_only_edl_file) }
|
||||
end
|
||||
|
||||
context "when video_editing_system is not adobe_premiere" do
|
||||
subject { build(:video, video_editing_system: "avid") }
|
||||
|
||||
it { is_expected.not_to validate_attachment_of(:audio_only_edl_file) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "enums" do
|
||||
it { is_expected.to define_enum_for(:analysis_status).with_values(not_started: 0, pending: 1, success: 2, failure: 3).with_prefix(:analysis) }
|
||||
it { is_expected.to define_enum_for(:audio_analysis_status).with_values(not_started: 0, pending: 1, success: 2, failure: 3).with_prefix(:audio_analysis) }
|
||||
it { is_expected.to define_enum_for(:video_editing_system).with_values(avid: 0, adobe_premiere: 1) }
|
||||
end
|
||||
end
|
||||
104
spec/models/zoom_meeting_spec.rb
Normal file
104
spec/models/zoom_meeting_spec.rb
Normal file
@@ -0,0 +1,104 @@
|
||||
require 'rails_helper'
|
||||
require 'zoom_gateway'
|
||||
|
||||
RSpec.describe ZoomMeeting, type: :model do
|
||||
let(:zoom_meeting) { build(:zoom_meeting, api_meeting_id: nil) }
|
||||
let(:meeting_dictionary) { {"start_url" => "https://start_url", "join_url" => "https://join_url"} }
|
||||
|
||||
before :all do
|
||||
WebMock.disable_net_connect!(allow_localhost: true)
|
||||
end
|
||||
|
||||
before :each do
|
||||
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).and_return(meeting_dictionary)
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return("meeting_id")
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return("host_id")
|
||||
end
|
||||
|
||||
|
||||
describe "attachments" do
|
||||
it { is_expected.to respond_to(:recording) }
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
context '#recording' do
|
||||
it { is_expected.to allow_content_type("video/mp4").for(:recording) }
|
||||
it { is_expected.not_to allow_content_types("image/png").for(:recording) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:zoom_user) }
|
||||
it { is_expected.to belong_to(:project).optional(true) }
|
||||
end
|
||||
|
||||
describe 'after_create' do
|
||||
it 'should assign api meeting id' do
|
||||
expect {
|
||||
zoom_meeting.save
|
||||
}.to change { zoom_meeting.api_meeting_id }
|
||||
end
|
||||
end
|
||||
|
||||
describe ".meeting" do
|
||||
it 'returns meeting dictionary' do
|
||||
expect(zoom_meeting.meeting).to eq(meeting_dictionary)
|
||||
end
|
||||
|
||||
it 'recreates meeting if the current on is expired' do
|
||||
# set the meeting id
|
||||
zoom_meeting.save
|
||||
|
||||
# simulate expiration
|
||||
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).with("meeting_id").and_raise(ZoomGateway::MeetingExpired)
|
||||
allow_any_instance_of(ZoomGateway).to receive(:find_meeting).with("new_meeting_id").and_return(meeting_dictionary)
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_meeting).and_return("new_meeting_id")
|
||||
|
||||
expect {
|
||||
zoom_meeting.meeting
|
||||
}.to change { zoom_meeting.api_meeting_id }
|
||||
end
|
||||
end
|
||||
|
||||
describe '.meeting_url' do
|
||||
before do
|
||||
zoom_meeting.api_meeting_id = "meeting_id"
|
||||
zoom_meeting.save
|
||||
end
|
||||
|
||||
context 'meeting is already started' do
|
||||
it 'returns join_url' do
|
||||
zoom_meeting.started!
|
||||
expect(zoom_meeting.meeting_url).to eq('https://join_url')
|
||||
end
|
||||
end
|
||||
|
||||
context 'meeting is not started yet' do
|
||||
it 'return start_url' do
|
||||
zoom_meeting.created!
|
||||
expect(zoom_meeting.meeting_url).to eq('https://start_url')
|
||||
end
|
||||
end
|
||||
|
||||
context 'meeting is ended' do
|
||||
it 'returns start_url' do
|
||||
zoom_meeting.ended!
|
||||
expect(zoom_meeting.meeting_url).to eq('https://start_url')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".join_url" do
|
||||
it "delegates to the meeting hash" do
|
||||
expect(zoom_meeting.meeting).to receive(:[]).with("join_url")
|
||||
zoom_meeting.join_url
|
||||
end
|
||||
end
|
||||
|
||||
describe ".start_url" do
|
||||
it "delegates to the meeting hash" do
|
||||
expect(zoom_meeting.meeting).to receive(:[]).with("start_url")
|
||||
zoom_meeting.start_url
|
||||
end
|
||||
end
|
||||
end
|
||||
31
spec/models/zoom_user_spec.rb
Normal file
31
spec/models/zoom_user_spec.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ZoomUser, type: :model do
|
||||
describe 'associations' do
|
||||
it { is_expected.to have_many(:zoom_meetings).dependent(:nullify) }
|
||||
end
|
||||
|
||||
describe 'callbacks' do
|
||||
let(:zoom_user) { build(:zoom_user) }
|
||||
|
||||
context '#after_create' do
|
||||
it 'triggers create_api_user' do
|
||||
allow(zoom_user).to receive(:create_api_user)
|
||||
|
||||
zoom_user.run_callbacks(:create)
|
||||
expect(zoom_user).to have_received(:create_api_user)
|
||||
end
|
||||
|
||||
it 'assigns api_id' do
|
||||
allow_any_instance_of(ZoomGateway).to receive(:create_host).and_return("retrieved_api_id")
|
||||
|
||||
zoom_user.save
|
||||
expect(zoom_user.api_id).to eq "retrieved_api_id"
|
||||
end
|
||||
end
|
||||
|
||||
context '#before_destroy' do
|
||||
pending 'aborts if there is api_id assigned'
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user